[Midnightbsd-cvs] src [9914] trunk/sys/sparc64: sync with freebsd 10-stable

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Fri May 25 08:44:45 EDT 2018


Revision: 9914
          http://svnweb.midnightbsd.org/src/?rev=9914
Author:   laffer1
Date:     2018-05-25 08:44:45 -0400 (Fri, 25 May 2018)
Log Message:
-----------
sync with freebsd 10-stable

Added Paths:
-----------
    trunk/sys/sparc64/
    trunk/sys/sparc64/central/
    trunk/sys/sparc64/central/central.c
    trunk/sys/sparc64/compile/
    trunk/sys/sparc64/conf/
    trunk/sys/sparc64/conf/DEFAULTS
    trunk/sys/sparc64/conf/GENERIC
    trunk/sys/sparc64/conf/GENERIC.hints
    trunk/sys/sparc64/conf/Makefile
    trunk/sys/sparc64/conf/NOTES
    trunk/sys/sparc64/ebus/
    trunk/sys/sparc64/ebus/ebus.c
    trunk/sys/sparc64/ebus/ebusreg.h
    trunk/sys/sparc64/ebus/epic.c
    trunk/sys/sparc64/fhc/
    trunk/sys/sparc64/fhc/clkbrd.c
    trunk/sys/sparc64/fhc/clkbrdreg.h
    trunk/sys/sparc64/fhc/fhc.c
    trunk/sys/sparc64/fhc/fhcreg.h
    trunk/sys/sparc64/include/
    trunk/sys/sparc64/include/_align.h
    trunk/sys/sparc64/include/_bus.h
    trunk/sys/sparc64/include/_inttypes.h
    trunk/sys/sparc64/include/_limits.h
    trunk/sys/sparc64/include/_stdint.h
    trunk/sys/sparc64/include/_types.h
    trunk/sys/sparc64/include/asi.h
    trunk/sys/sparc64/include/asm.h
    trunk/sys/sparc64/include/asmacros.h
    trunk/sys/sparc64/include/atomic.h
    trunk/sys/sparc64/include/bus.h
    trunk/sys/sparc64/include/bus_common.h
    trunk/sys/sparc64/include/bus_dma.h
    trunk/sys/sparc64/include/bus_private.h
    trunk/sys/sparc64/include/cache.h
    trunk/sys/sparc64/include/ccr.h
    trunk/sys/sparc64/include/clock.h
    trunk/sys/sparc64/include/cmt.h
    trunk/sys/sparc64/include/counter.h
    trunk/sys/sparc64/include/cpu.h
    trunk/sys/sparc64/include/cpufunc.h
    trunk/sys/sparc64/include/db_machdep.h
    trunk/sys/sparc64/include/dcr.h
    trunk/sys/sparc64/include/elf.h
    trunk/sys/sparc64/include/endian.h
    trunk/sys/sparc64/include/exec.h
    trunk/sys/sparc64/include/fireplane.h
    trunk/sys/sparc64/include/float.h
    trunk/sys/sparc64/include/floatingpoint.h
    trunk/sys/sparc64/include/fp.h
    trunk/sys/sparc64/include/frame.h
    trunk/sys/sparc64/include/fsr.h
    trunk/sys/sparc64/include/gdb_machdep.h
    trunk/sys/sparc64/include/idprom.h
    trunk/sys/sparc64/include/ieee.h
    trunk/sys/sparc64/include/ieeefp.h
    trunk/sys/sparc64/include/in_cksum.h
    trunk/sys/sparc64/include/instr.h
    trunk/sys/sparc64/include/intr_machdep.h
    trunk/sys/sparc64/include/iommureg.h
    trunk/sys/sparc64/include/iommuvar.h
    trunk/sys/sparc64/include/jbus.h
    trunk/sys/sparc64/include/kdb.h
    trunk/sys/sparc64/include/kerneldump.h
    trunk/sys/sparc64/include/ktr.h
    trunk/sys/sparc64/include/limits.h
    trunk/sys/sparc64/include/lsu.h
    trunk/sys/sparc64/include/mcntl.h
    trunk/sys/sparc64/include/md_var.h
    trunk/sys/sparc64/include/memdev.h
    trunk/sys/sparc64/include/metadata.h
    trunk/sys/sparc64/include/nexusvar.h
    trunk/sys/sparc64/include/ofw_machdep.h
    trunk/sys/sparc64/include/ofw_mem.h
    trunk/sys/sparc64/include/ofw_nexus.h
    trunk/sys/sparc64/include/param.h
    trunk/sys/sparc64/include/pcb.h
    trunk/sys/sparc64/include/pcpu.h
    trunk/sys/sparc64/include/pmap.h
    trunk/sys/sparc64/include/pmc_mdep.h
    trunk/sys/sparc64/include/proc.h
    trunk/sys/sparc64/include/profile.h
    trunk/sys/sparc64/include/pstate.h
    trunk/sys/sparc64/include/ptrace.h
    trunk/sys/sparc64/include/reg.h
    trunk/sys/sparc64/include/reloc.h
    trunk/sys/sparc64/include/resource.h
    trunk/sys/sparc64/include/runq.h
    trunk/sys/sparc64/include/sc_machdep.h
    trunk/sys/sparc64/include/setjmp.h
    trunk/sys/sparc64/include/sf_buf.h
    trunk/sys/sparc64/include/sigframe.h
    trunk/sys/sparc64/include/signal.h
    trunk/sys/sparc64/include/smp.h
    trunk/sys/sparc64/include/stack.h
    trunk/sys/sparc64/include/stdarg.h
    trunk/sys/sparc64/include/sysarch.h
    trunk/sys/sparc64/include/tick.h
    trunk/sys/sparc64/include/tlb.h
    trunk/sys/sparc64/include/trap.h
    trunk/sys/sparc64/include/tsb.h
    trunk/sys/sparc64/include/tstate.h
    trunk/sys/sparc64/include/tte.h
    trunk/sys/sparc64/include/ucontext.h
    trunk/sys/sparc64/include/upa.h
    trunk/sys/sparc64/include/utrap.h
    trunk/sys/sparc64/include/varargs.h
    trunk/sys/sparc64/include/vdso.h
    trunk/sys/sparc64/include/ver.h
    trunk/sys/sparc64/include/vm.h
    trunk/sys/sparc64/include/vmparam.h
    trunk/sys/sparc64/include/watch.h
    trunk/sys/sparc64/include/wstate.h
    trunk/sys/sparc64/isa/
    trunk/sys/sparc64/isa/isa.c
    trunk/sys/sparc64/isa/isa_dma.c
    trunk/sys/sparc64/isa/ofw_isa.c
    trunk/sys/sparc64/isa/ofw_isa.h
    trunk/sys/sparc64/pci/
    trunk/sys/sparc64/pci/apb.c
    trunk/sys/sparc64/pci/fire.c
    trunk/sys/sparc64/pci/firereg.h
    trunk/sys/sparc64/pci/firevar.h
    trunk/sys/sparc64/pci/ofw_pci.c
    trunk/sys/sparc64/pci/ofw_pci.h
    trunk/sys/sparc64/pci/ofw_pci_if.m
    trunk/sys/sparc64/pci/ofw_pcib.c
    trunk/sys/sparc64/pci/ofw_pcib_subr.c
    trunk/sys/sparc64/pci/ofw_pcib_subr.h
    trunk/sys/sparc64/pci/ofw_pcibus.c
    trunk/sys/sparc64/pci/psycho.c
    trunk/sys/sparc64/pci/psychoreg.h
    trunk/sys/sparc64/pci/psychovar.h
    trunk/sys/sparc64/pci/sbbc.c
    trunk/sys/sparc64/pci/schizo.c
    trunk/sys/sparc64/pci/schizoreg.h
    trunk/sys/sparc64/pci/schizovar.h
    trunk/sys/sparc64/sbus/
    trunk/sys/sparc64/sbus/dma_sbus.c
    trunk/sys/sparc64/sbus/lsi64854.c
    trunk/sys/sparc64/sbus/lsi64854reg.h
    trunk/sys/sparc64/sbus/lsi64854var.h
    trunk/sys/sparc64/sbus/ofw_sbus.h
    trunk/sys/sparc64/sbus/sbus.c
    trunk/sys/sparc64/sbus/sbusreg.h
    trunk/sys/sparc64/sbus/sbusvar.h
    trunk/sys/sparc64/sparc64/
    trunk/sys/sparc64/sparc64/ata_machdep.c
    trunk/sys/sparc64/sparc64/autoconf.c
    trunk/sys/sparc64/sparc64/bus_machdep.c
    trunk/sys/sparc64/sparc64/cache.c
    trunk/sys/sparc64/sparc64/cam_machdep.c
    trunk/sys/sparc64/sparc64/cheetah.c
    trunk/sys/sparc64/sparc64/clock.c
    trunk/sys/sparc64/sparc64/counter.c
    trunk/sys/sparc64/sparc64/db_disasm.c
    trunk/sys/sparc64/sparc64/db_hwwatch.c
    trunk/sys/sparc64/sparc64/db_interface.c
    trunk/sys/sparc64/sparc64/db_trace.c
    trunk/sys/sparc64/sparc64/dump_machdep.c
    trunk/sys/sparc64/sparc64/eeprom.c
    trunk/sys/sparc64/sparc64/elf_machdep.c
    trunk/sys/sparc64/sparc64/exception.S
    trunk/sys/sparc64/sparc64/gdb_machdep.c
    trunk/sys/sparc64/sparc64/genassym.c
    trunk/sys/sparc64/sparc64/identcpu.c
    trunk/sys/sparc64/sparc64/in_cksum.c
    trunk/sys/sparc64/sparc64/interrupt.S
    trunk/sys/sparc64/sparc64/intr_machdep.c
    trunk/sys/sparc64/sparc64/iommu.c
    trunk/sys/sparc64/sparc64/jbusppm.c
    trunk/sys/sparc64/sparc64/locore.S
    trunk/sys/sparc64/sparc64/machdep.c
    trunk/sys/sparc64/sparc64/mem.c
    trunk/sys/sparc64/sparc64/mp_exception.S
    trunk/sys/sparc64/sparc64/mp_locore.S
    trunk/sys/sparc64/sparc64/mp_machdep.c
    trunk/sys/sparc64/sparc64/nexus.c
    trunk/sys/sparc64/sparc64/ofw_machdep.c
    trunk/sys/sparc64/sparc64/pmap.c
    trunk/sys/sparc64/sparc64/prof_machdep.c
    trunk/sys/sparc64/sparc64/rtc.c
    trunk/sys/sparc64/sparc64/rwindow.c
    trunk/sys/sparc64/sparc64/sc_machdep.c
    trunk/sys/sparc64/sparc64/schppm.c
    trunk/sys/sparc64/sparc64/spitfire.c
    trunk/sys/sparc64/sparc64/ssm.c
    trunk/sys/sparc64/sparc64/stack_machdep.c
    trunk/sys/sparc64/sparc64/support.S
    trunk/sys/sparc64/sparc64/swtch.S
    trunk/sys/sparc64/sparc64/sys_machdep.c
    trunk/sys/sparc64/sparc64/tick.c
    trunk/sys/sparc64/sparc64/tlb.c
    trunk/sys/sparc64/sparc64/trap.c
    trunk/sys/sparc64/sparc64/tsb.c
    trunk/sys/sparc64/sparc64/uio_machdep.c
    trunk/sys/sparc64/sparc64/upa.c
    trunk/sys/sparc64/sparc64/vm_machdep.c
    trunk/sys/sparc64/sparc64/zeus.c

Added: trunk/sys/sparc64/central/central.c
===================================================================
--- trunk/sys/sparc64/central/central.c	                        (rev 0)
+++ trunk/sys/sparc64/central/central.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,300 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Jake Burkholder.
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/central/central.c 227848 2011-11-22 21:55:40Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <sys/rman.h>
+
+#include <sparc64/sbus/ofw_sbus.h>
+
+struct central_devinfo {
+	struct ofw_bus_devinfo	cdi_obdinfo;
+	struct resource_list	cdi_rl;
+};
+
+struct central_softc {
+	int			sc_nrange;
+	struct sbus_ranges	*sc_ranges;
+};
+
+static device_probe_t central_probe;
+static device_attach_t central_attach;
+static bus_print_child_t central_print_child;
+static bus_probe_nomatch_t central_probe_nomatch;
+static bus_alloc_resource_t central_alloc_resource;
+static bus_adjust_resource_t central_adjust_resource;
+static bus_get_resource_list_t central_get_resource_list;
+static ofw_bus_get_devinfo_t central_get_devinfo;
+
+static int central_print_res(struct central_devinfo *);
+
+static device_method_t central_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		central_probe),
+	DEVMETHOD(device_attach,	central_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	central_print_child),
+	DEVMETHOD(bus_probe_nomatch,	central_probe_nomatch),
+	DEVMETHOD(bus_alloc_resource,	central_alloc_resource),
+	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	central_adjust_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_rl_release_resource),
+	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	DEVMETHOD(bus_get_resource_list, central_get_resource_list),
+	DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	central_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	DEVMETHOD_END
+};
+
+static driver_t central_driver = {
+	"central",
+	central_methods,
+	sizeof(struct central_softc),
+};
+
+static devclass_t central_devclass;
+
+EARLY_DRIVER_MODULE(central, nexus, central_driver, central_devclass, 0, 0,
+    BUS_PASS_BUS);
+MODULE_DEPEND(fhc, nexus, 1, 1, 1);
+MODULE_VERSION(central, 1);
+
+static int
+central_probe(device_t dev)
+{
+
+	if (strcmp(ofw_bus_get_name(dev), "central") == 0) {
+		device_set_desc(dev, "central");
+		return (0);
+	}
+	return (ENXIO);
+}
+
+static int
+central_attach(device_t dev)
+{
+	struct central_devinfo *cdi;
+	struct sbus_regs *reg;
+	struct central_softc *sc;
+	phandle_t child;
+	phandle_t node;
+	device_t cdev;
+	int nreg;
+	int i;
+
+	sc = device_get_softc(dev);
+	node = ofw_bus_get_node(dev);
+
+	sc->sc_nrange = OF_getprop_alloc(node, "ranges",
+	    sizeof(*sc->sc_ranges), (void **)&sc->sc_ranges);
+	if (sc->sc_nrange == -1) {
+		device_printf(dev, "can't get ranges\n");
+		return (ENXIO);
+	}
+
+	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+		cdi = malloc(sizeof(*cdi), M_DEVBUF, M_WAITOK | M_ZERO);
+		if (ofw_bus_gen_setup_devinfo(&cdi->cdi_obdinfo, child) != 0) {
+			free(cdi, M_DEVBUF);
+			continue;
+		}
+		nreg = OF_getprop_alloc(child, "reg", sizeof(*reg),
+		    (void **)&reg);
+		if (nreg == -1) {
+			device_printf(dev, "<%s>: incomplete\n",
+			    cdi->cdi_obdinfo.obd_name);
+			ofw_bus_gen_destroy_devinfo(&cdi->cdi_obdinfo);
+			free(cdi, M_DEVBUF);
+			continue;
+		}
+		resource_list_init(&cdi->cdi_rl);
+		for (i = 0; i < nreg; i++)
+			resource_list_add(&cdi->cdi_rl, SYS_RES_MEMORY, i,
+			    reg[i].sbr_offset, reg[i].sbr_offset +
+			    reg[i].sbr_size, reg[i].sbr_size);
+		free(reg, M_OFWPROP);
+		cdev = device_add_child(dev, NULL, -1);
+		if (cdev == NULL) {
+			device_printf(dev, "<%s>: device_add_child failed\n",
+			    cdi->cdi_obdinfo.obd_name);
+			resource_list_free(&cdi->cdi_rl);
+			ofw_bus_gen_destroy_devinfo(&cdi->cdi_obdinfo);
+			free(cdi, M_DEVBUF);
+			continue;
+		}
+		device_set_ivars(cdev, cdi);
+	}
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+central_adjust_resource(device_t bus __unused, device_t child __unused,
+    int type __unused, struct resource *r __unused, u_long start __unused,
+    u_long end __unused)
+{
+
+	return (ENXIO);
+}
+
+static int
+central_print_child(device_t dev, device_t child)
+{
+	int rv;
+
+	rv = bus_print_child_header(dev, child);
+	rv += central_print_res(device_get_ivars(child));
+	rv += bus_print_child_footer(dev, child);
+	return (rv);
+}
+
+static void
+central_probe_nomatch(device_t dev, device_t child)
+{
+	const char *type;
+
+	device_printf(dev, "<%s>", ofw_bus_get_name(child));
+	central_print_res(device_get_ivars(child));
+	type = ofw_bus_get_type(child);
+	printf(" type %s (no driver attached)\n",
+	    type != NULL ? type : "unknown");
+}
+
+static struct resource *
+central_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct resource_list *rl;
+	struct resource_list_entry *rle;
+	struct central_softc *sc;
+	struct resource *res;
+	bus_addr_t coffset;
+	bus_addr_t cend;
+	bus_addr_t phys;
+	int isdefault;
+	int passthrough;
+	int i;
+
+	isdefault = (start == 0UL && end == ~0UL);
+	passthrough = (device_get_parent(child) != bus);
+	res = NULL;
+	rle = NULL;
+	rl = BUS_GET_RESOURCE_LIST(bus, child);
+	sc = device_get_softc(bus);
+	switch (type) {
+	case SYS_RES_IRQ:
+		return (resource_list_alloc(rl, bus, child, type, rid, start,
+		    end, count, flags));
+	case SYS_RES_MEMORY:
+		if (!passthrough) {
+			rle = resource_list_find(rl, type, *rid);
+			if (rle == NULL)
+				return (NULL);
+			if (rle->res != NULL)
+				panic("%s: resource entry is busy", __func__);
+			if (isdefault) {
+				start = rle->start;
+				count = ulmax(count, rle->count);
+				end = ulmax(rle->end, start + count - 1);
+			}
+		}
+		for (i = 0; i < sc->sc_nrange; i++) {
+			coffset = sc->sc_ranges[i].coffset;
+			cend = coffset + sc->sc_ranges[i].size - 1;
+			if (start >= coffset && end <= cend) {
+				start -= coffset;
+				end -= coffset;
+				phys = sc->sc_ranges[i].poffset |
+				    ((bus_addr_t)sc->sc_ranges[i].pspace << 32);
+				res = bus_generic_alloc_resource(bus, child,
+				    type, rid, phys + start, phys + end,
+				    count, flags);
+				if (!passthrough)
+					rle->res = res;
+				break;
+			}
+		}
+		break;
+	}
+	return (res);
+}
+
+static struct resource_list *
+central_get_resource_list(device_t bus, device_t child)
+{
+	struct central_devinfo *cdi;
+
+	cdi = device_get_ivars(child);
+	return (&cdi->cdi_rl);
+}
+
+static const struct ofw_bus_devinfo *
+central_get_devinfo(device_t bus, device_t child)
+{
+	struct central_devinfo *cdi;
+
+	cdi = device_get_ivars(child);
+	return (&cdi->cdi_obdinfo);
+}
+
+static int
+central_print_res(struct central_devinfo *cdi)
+{
+
+	return (resource_list_print_type(&cdi->cdi_rl, "mem", SYS_RES_MEMORY,
+	    "%#lx"));
+}


Property changes on: trunk/sys/sparc64/central/central.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/conf/DEFAULTS
===================================================================
--- trunk/sys/sparc64/conf/DEFAULTS	                        (rev 0)
+++ trunk/sys/sparc64/conf/DEFAULTS	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,23 @@
+#
+# DEFAULTS -- Default kernel configuration file for FreeBSD/sparc64
+# $MidnightBSD$
+# $FreeBSD: stable/10/sys/sparc64/conf/DEFAULTS 232619 2012-03-06 20:01:25Z attilio $
+
+machine		sparc64
+
+# Pseudo devices.
+device		mem		# Memory and kernel memory devices
+
+# UART chips on this platform
+device		uart_ns8250
+device		uart_sab82532
+device		uart_z8530
+
+# Default partitioning schemes
+options 	GEOM_PART_BSD
+options 	GEOM_PART_VTOC8
+
+# Let sunkbd emulate an AT keyboard by default.
+options 	SUNKBD_EMULATE_ATKBD
+
+options 	NEW_PCIB


Property changes on: trunk/sys/sparc64/conf/DEFAULTS
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/sparc64/conf/GENERIC
===================================================================
--- trunk/sys/sparc64/conf/GENERIC	                        (rev 0)
+++ trunk/sys/sparc64/conf/GENERIC	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,240 @@
+#
+# GENERIC -- Generic kernel configuration file for FreeBSD/sparc64
+#
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
+#
+#    http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# The handbook is also available locally in /usr/share/doc/handbook
+# if you've installed the doc distribution, otherwise always see the
+# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
+# latest information.
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
+# in NOTES.
+#
+# $MidnightBSD$
+# $FreeBSD: stable/10/sys/sparc64/conf/GENERIC 284665 2015-06-21 06:28:26Z trasz $
+
+cpu		SUN4U
+ident		GENERIC
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+
+# Platforms supported
+#	At this time all platforms are supported, as-is.
+
+options 	SCHED_ULE		# ULE scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+options 	FFS			# Berkeley Fast Filesystem
+options 	SOFTUPDATES		# Enable FFS soft updates support
+options 	UFS_ACL			# Support for access control lists
+options 	UFS_DIRHASH		# Improve performance on big directories
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	MD_ROOT			# MD is a potential root device
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+#options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	GEOM_PART_GPT		# GUID Partition Tables.
+options 	GEOM_LABEL		# Provides labelization
+options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
+options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
+options 	COMPAT_FREEBSD7		# Compatible with FreeBSD7
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	STACK			# stack(9) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	PRINTF_BUFR_SIZE=128	# Prevent printf output being interspersed.
+options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
+options 	AUDIT			# Security event auditing
+options 	CAPABILITY_MODE		# Capsicum capability mode
+options 	CAPABILITIES		# Capsicum capabilities
+options 	PROCDESC		# Support for process descriptors
+options 	MAC			# TrustedBSD MAC Framework
+options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
+options 	RACCT			# Resource accounting framework
+options 	RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default
+options 	RCTL			# Resource limits
+
+# Debugging support.  Always need this:
+options 	KDB			# Enable kernel debugger support.
+options 	KDB_TRACE		# Print a stack trace for a panic.
+
+# Make an SMP-capable kernel by default
+options 	SMP			# Symmetric MultiProcessor Kernel
+
+# Standard busses
+device		ebus
+device		isa
+device		pci
+device		sbus
+device		central
+device		fhc
+
+# Floppy drives
+#device		fdc
+
+# ATA controllers
+device		ahci		# AHCI-compatible SATA controllers
+device		ata		# Legacy ATA/SATA controllers
+device		mvs		# Marvell 88SX50XX/88SX60XX/88SX70XX/SoC SATA
+device		siis		# SiliconImage SiI3124/SiI3132/SiI3531 SATA
+
+# SCSI Controllers
+device		ahc		# AHA2940 and onboard AIC7xxx devices
+options 	AHC_ALLOW_MEMIO	# Attempt to use memory mapped I/O
+options 	AHC_REG_PRETTY_PRINT	# Print register bitfields in debug
+					# output.  Adds ~128k to driver.
+device		esp		# AMD Am53C974, Sun ESP and FAS	families
+device		isp		# Qlogic family
+device		ispfw		# Firmware module for Qlogic host adapters
+device		mpt		# LSI-Logic MPT-Fusion
+device		mps		# LSI-Logic MPT-Fusion 2
+device		mpr		# LSI-Logic MPT-Fusion 3
+device		sym		# NCR/Symbios/LSI Logic 53C8XX/53C1010/53C1510D
+
+# ATA/SCSI peripherals
+device		scbus		# SCSI bus (required for ATA/SCSI)
+device		ch		# SCSI media changers
+device		da		# Direct Access (disks)
+device		sa		# Sequential Access (tape etc)
+device		cd		# CD
+device		pass		# Passthrough device (direct ATA/SCSI access)
+device		ses		# Enclosure Services (SES and SAF-TE)
+#device		ctl		# CAM Target Layer
+
+# RAID controllers
+#device		amr		# AMI MegaRAID
+#device		mlx		# Mylex DAC960 family
+
+# atkbdc0 controls both the keyboard and the PS/2 mouse
+device		atkbdc		# AT keyboard controller
+device		atkbd		# AT keyboard
+device		psm		# PS/2 mouse
+
+device		kbdmux		# keyboard multiplexer
+
+# syscons is the default console driver, resembling an SCO console
+device		sc
+device		creator		# Creator, Creator3D and Elite3D framebuffers
+device		machfb		# ATI Mach64 framebuffers
+device		splash		# Splash screen and screen saver support
+options 	KBD_INSTALL_CDEV # install a CDEV entry in /dev
+
+# Builtin hardware
+device		auxio		# auxiliary I/O device
+device		eeprom		# eeprom (really a front-end for the MK48Txx)
+device		mk48txx		# Mostek MK48Txx clocks
+device		rtc		# rtc (really a front-end for the MC146818)
+device		mc146818	# Motorola MC146818 and compatible clocks
+device		epic		# Sun Fire V215/V245 LEDs
+device		sbbc		# Sun BootBus controller (time-of-day clock for
+				# Serengeti and StarCat, console for Serengeti,
+				# requires device uart)
+
+# Serial (COM) ports
+device		puc		# Multi-channel uarts
+device		scc		# Serial communications controllers.
+device		uart		# Multi-uart driver
+
+# Parallel port
+#device		ppc
+#device		ppbus		# Parallel port bus (required)
+#device		lpt		# Printer
+#device		ppi		# Parallel port interface device
+#device		vpo		# Requires scbus and da
+
+# PCI Ethernet NICs.
+#device		de		# DEC/Intel DC21x4x (``Tulip'')
+device		em		# Intel PRO/1000 adapter Gigabit Ethernet Card
+#device		ixgb		# Intel PRO/10GbE Ethernet Card
+device		le		# AMD Am7900 LANCE and Am79C9xx PCnet
+device		ti		# Alteon Networks Tigon I/II gigabit Ethernet
+device		txp		# 3Com 3cR990 (``Typhoon'')
+#device		vx		# 3Com 3c590, 3c595 (``Vortex'')
+
+# PCI Ethernet NICs that use the common MII bus controller code.
+# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs!
+device		miibus		# MII bus support
+#device		bfe		# Broadcom BCM440x 10/100 Ethernet
+device		bge		# Broadcom BCM570xx Gigabit Ethernet
+device		cas		# Sun Cassini/Cassini+ and NS DP83065 Saturn
+device		dc		# DEC/Intel 21143 and various workalikes
+device		fxp		# Intel EtherExpress PRO/100B (82557, 82558)
+device		gem		# Sun GEM/Sun ERI/Apple GMAC
+device		hme		# Sun HME (Happy Meal Ethernet)
+device		nge		# NatSemi DP83820 gigabit Ethernet
+#device		pcn		# AMD Am79C97x PCI 10/100 (precedence over 'le')
+device		re		# RealTek 8139C+/8169/8169S/8110S
+device		rl		# RealTek 8129/8139
+device		sf		# Adaptec AIC-6915 (``Starfire'')
+device		sis		# Silicon Integrated Systems SiS 900/SiS 7016
+device		sk		# SysKonnect SK-984x & SK-982x gigabit Ethernet
+device		ste		# Sundance ST201 (D-Link DFE-550TX)
+device		stge		# Sundance/Tamarack TC9021 gigabit Ethernet
+#device		tl		# Texas Instruments ThunderLAN
+#device		tx		# SMC EtherPower II (83c170 ``EPIC'')
+device		vr		# VIA Rhine, Rhine II
+#device		wb		# Winbond W89C840F
+device		xl		# 3Com 3c90x (``Boomerang'', ``Cyclone'')
+
+# Wireless NIC cards
+device		wlan		# 802.11 support
+options 	IEEE80211_DEBUG	# enable debug msgs
+options 	IEEE80211_AMPDU_AGE	# age frames in AMPDU reorder q's
+options 	IEEE80211_SUPPORT_MESH	# enable 802.11s D3.0 support
+device		wlan_wep	# 802.11 WEP support
+device		wlan_ccmp	# 802.11 CCMP support
+device		wlan_tkip	# 802.11 TKIP support
+device		wlan_amrr	# AMRR transmit rate control algorithm
+device		ath		# Atheros NICs
+device		ath_pci		# Atheros pci/cardbus glue
+device		ath_hal		# Atheros HAL (Hardware Access Layer)
+options 	AH_SUPPORT_AR5416	# enable AR5416 tx/rx descriptors
+device		ath_rate_sample	# SampleRate tx rate control for ath
+
+# Pseudo devices.
+device		loop		# Network loopback
+device		random		# Entropy device
+device		ether		# Ethernet support
+device		vlan		# 802.1Q VLAN support
+device		tun		# Packet tunnel.
+device		md		# Memory "disks"
+device		gif		# IPv6 and IPv4 tunneling
+device		faith		# IPv6-to-IPv4 relaying (translation)
+device		firmware	# firmware assist module
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device		bpf		# Berkeley packet filter
+
+# USB support
+options 	USB_DEBUG	# enable debug msgs
+device		uhci		# UHCI PCI->USB interface
+device		ohci		# OHCI PCI->USB interface
+device		ehci		# EHCI PCI->USB interface (USB 2.0)
+device		usb		# USB Bus (required)
+device		ukbd		# Keyboard
+device		umass		# Disks/Mass storage - Requires scbus and da
+
+# Sound support
+device		sound		# Generic sound driver (required)
+device		snd_audiocs	# Crystal Semiconductor CS4231
+device		snd_es137x	# Ensoniq AudioPCI ES137x
+device		snd_t4dwave	# Acer Labs M5451


Property changes on: trunk/sys/sparc64/conf/GENERIC
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/sparc64/conf/GENERIC.hints
===================================================================
--- trunk/sys/sparc64/conf/GENERIC.hints	                        (rev 0)
+++ trunk/sys/sparc64/conf/GENERIC.hints	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,2 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/sys/sparc64/conf/GENERIC.hints 81615 2001-08-14 03:27:02Z jake $


Property changes on: trunk/sys/sparc64/conf/GENERIC.hints
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/sparc64/conf/Makefile
===================================================================
--- trunk/sys/sparc64/conf/Makefile	                        (rev 0)
+++ trunk/sys/sparc64/conf/Makefile	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,6 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/sys/sparc64/conf/Makefile 201813 2010-01-08 18:57:31Z bz $
+
+TARGET=sparc64
+
+.include "${.CURDIR}/../../conf/makeLINT.mk"


Property changes on: trunk/sys/sparc64/conf/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/conf/NOTES
===================================================================
--- trunk/sys/sparc64/conf/NOTES	                        (rev 0)
+++ trunk/sys/sparc64/conf/NOTES	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,154 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/sys/sparc64/conf/NOTES 206451 2010-04-10 11:52:12Z marius $
+#
+# This file contains machine dependent kernel configuration notes.  For
+# machine independent notes, look in /sys/conf/NOTES.
+
+

+#####################################################################
+# CPU OPTIONS
+
+#
+# You must specify at least one CPU (the one you intend to run on);
+# deleting the specification for CPUs you don't need to use may make
+# parts of the system run faster.
+# XXX: On the Sparc64, there is only one CPU type
+cpu		SUN4U
+
+

+#####################################################################
+# HARDWARE BUS CONFIGURATION
+
+device		ebus
+device		isa
+device		pci
+device		sbus
+device		central
+device		fhc
+
+

+#####################################################################
+# HARDWARE DEVICE CONFIGURATION
+
+#
+# Mandatory devices:
+#
+
+device		eeprom		# eeprom (really a front-end for the MK48Txx)
+device		mk48txx		# Mostek MK48Txx clocks
+device		rtc		# rtc (really a front-end for the MC146818)
+device		mc146818	# Motorola MC146818 and compatible clocks
+device		sbbc		# Sun BootBus controller
+
+#
+# Optional devices:
+#
+
+device		auxio		# auxiliary I/O device
+device		epic		# Sun Fire V215/V245 LEDs
+device		creator		# Creator, Creator3D and Elite3D framebuffers
+device		machfb		# ATI Mach64 framebuffers
+
+device		ofw_console	# Open Firmware console device
+option 		OFWCONS_POLL_HZ=4 # 20 or more works best on Ultra2
+
+# PS/2 mouse
+device		psm
+
+# Options for psm:
+options 	PSM_HOOKRESUME		#hook the system resume event, useful
+					#for some laptops
+options 	PSM_RESETAFTERSUSPEND	#reset the device at the resume event
+
+# The keyboard controller; it controls the keyboard and the PS/2 mouse.
+device		atkbdc
+
+# The AT keyboard
+device		atkbd
+
+# Options for atkbd:
+options 	ATKBD_DFLT_KEYMAP	# specify the built-in keymap
+makeoptions	ATKBD_DFLT_KEYMAP=jp.106
+
+# `flags' for atkbd:
+#       0x01    Force detection of keyboard, else we always assume a keyboard
+#       0x02    Don't reset keyboard, useful for some newer ThinkPads
+#	0x03	Force detection and avoid reset, might help with certain
+#		dockingstations
+#       0x04    Old-style (XT) keyboard support, useful for older ThinkPads
+
+# Sun type 4/5/6 RS-232 at TTL keyboard
+#device		sunkbd
+
+# Options for sunkbd:
+options 	SUNKBD_EMULATE_ATKBD	# allows to use the AT keyboard maps
+					# in share/syscons/keymaps, required
+					# for SUNKBD_DFLT_KEYMAP and kbdmux
+options 	SUNKBD_DFLT_KEYMAP	# specify the built-in keymap
+makeoptions	SUNKBD_DFLT_KEYMAP=jp.106
+
+

+#####################################################################
+# Devices we don't want to deal with
+
+nodevice	daemon_saver
+nodevice	snake_saver
+nodevice	star_saver
+nodevice	bktr
+nodevice	fdc
+nodevice	ppc
+nodevice	snd_ad1816
+nodevice	snd_als4000
+nodevice	snd_cmi
+nodevice	snd_cs4281
+nodevice	snd_csa
+nodevice	snd_ds1
+nodevice	snd_emu10k1
+nodevice	snd_ess
+nodevice	snd_fm801
+nodevice	snd_gusc
+nodevice	snd_ich
+nodevice	snd_maestro
+nodevice	snd_maestro3
+nodevice	snd_mss
+nodevice	snd_neomagic
+nodevice	snd_sb16
+nodevice	snd_sb8
+nodevice	snd_sbc
+nodevice	snd_solo
+nodevice	snd_t4dwave
+nodevice	snd_via8233
+nodevice	snd_via82c686
+nodevice	snd_vibes
+nodevice	snd_uaudio
+nodevice	aha
+nodevice	bt
+nodevice	wds
+nodevice	ep
+nodevice	ex
+
+

+#####################################################################
+# Options we don't want to deal with
+
+nooption	FDC_DEBUG
+nooption	COMPAT_FREEBSD4
+nooption	SC_RENDER_DEBUG
+nooption	SC_DEBUG_LEVEL
+nooption	PPC_DEBUG
+nooption	PPC_PROBE_CHIPSET
+nooption	SC_NO_SUSPEND_VTYSWITCH
+nooption	SC_NO_FONT_LOADING
+nooption	SC_KERNEL_CONS_REV_ATTR
+nooption	SC_KERNEL_CONS_ATTR
+nooption	SC_NORM_REV_ATTR
+nooption	SC_NORM_ATTR
+nooption	SC_DFLT_FONT
+nooption	SC_ALT_MOUSE_IMAGE
+nooption	EXT2FS
+
+

+#####################################################################
+# Make options we don't want to deal with
+
+nomakeoption	SC_DFLT_FONT


Property changes on: trunk/sys/sparc64/conf/NOTES
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/sparc64/ebus/ebus.c
===================================================================
--- trunk/sys/sparc64/ebus/ebus.c	                        (rev 0)
+++ trunk/sys/sparc64/ebus/ebus.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,729 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * Copyright (c) 2009 by Marius Strobl <marius at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: ebus.c,v 1.52 2008/05/29 14:51:26 mrg Exp
+ */
+/*-
+ * Copyright (c) 2001 Thomas Moestl <tmm at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/ebus/ebus.c 292785 2015-12-27 17:51:10Z marius $");
+
+/*
+ * Driver for JBus to EBus and PCI to EBus bridges
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#ifndef SUN4V
+#include <machine/bus_common.h>
+#endif
+#include <machine/intr_machdep.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <sparc64/pci/ofw_pci.h>
+
+/*
+ * The register, interrupt map and for the PCI variant also the ranges
+ * properties are identical to the ISA ones.
+ */
+#include <sparc64/isa/ofw_isa.h>
+
+struct ebus_nexus_ranges {
+	uint32_t	child_hi;
+	uint32_t	child_lo;
+	uint32_t	phys_hi;
+	uint32_t	phys_lo;
+	uint32_t	size;
+};
+
+struct ebus_devinfo {
+	struct ofw_bus_devinfo	edi_obdinfo;
+	struct resource_list	edi_rl;
+};
+
+struct ebus_rinfo {
+	int			eri_rtype;
+	struct rman		eri_rman;
+	struct resource		*eri_res;
+};
+
+struct ebus_softc {
+	void			*sc_range;
+	struct ebus_rinfo	*sc_rinfo;
+
+	u_int			sc_flags;
+#define	EBUS_PCI		(1 << 0)
+
+	int			sc_nrange;
+
+	struct ofw_bus_iinfo	sc_iinfo;
+
+#ifndef SUN4V
+	uint32_t		sc_ign;
+#endif
+};
+
+static device_probe_t ebus_nexus_probe;
+static device_attach_t ebus_nexus_attach;
+static device_probe_t ebus_pci_probe;
+static device_attach_t ebus_pci_attach;
+static bus_print_child_t ebus_print_child;
+static bus_probe_nomatch_t ebus_probe_nomatch;
+static bus_alloc_resource_t ebus_alloc_resource;
+static bus_activate_resource_t ebus_activate_resource;
+static bus_adjust_resource_t ebus_adjust_resource;
+static bus_release_resource_t ebus_release_resource;
+static bus_setup_intr_t ebus_setup_intr;
+static bus_get_resource_list_t ebus_get_resource_list;
+static ofw_bus_get_devinfo_t ebus_get_devinfo;
+
+static int ebus_attach(device_t dev, struct ebus_softc *sc, phandle_t node);
+static struct ebus_devinfo *ebus_setup_dinfo(device_t dev,
+    struct ebus_softc *sc, phandle_t node);
+static void ebus_destroy_dinfo(struct ebus_devinfo *edi);
+static int ebus_print_res(struct ebus_devinfo *edi);
+
+static devclass_t ebus_devclass;
+
+static device_method_t ebus_nexus_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ebus_nexus_probe),
+	DEVMETHOD(device_attach,	ebus_nexus_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	ebus_print_child),
+	DEVMETHOD(bus_probe_nomatch,	ebus_probe_nomatch),
+	DEVMETHOD(bus_alloc_resource,	ebus_alloc_resource),
+	DEVMETHOD(bus_activate_resource, ebus_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	ebus_adjust_resource),
+	DEVMETHOD(bus_release_resource,	ebus_release_resource),
+	DEVMETHOD(bus_setup_intr,	ebus_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	DEVMETHOD(bus_get_resource_list, ebus_get_resource_list),
+	DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	ebus_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	DEVMETHOD_END
+};
+
+static driver_t ebus_nexus_driver = {
+	"ebus",
+	ebus_nexus_methods,
+	sizeof(struct ebus_softc),
+};
+
+/*
+ * NB: we rely on the interrupt controllers of the accompanying PCI-Express
+ * bridge to be registered as the nexus variant of the EBus bridges doesn't
+ * employ its own one.
+ */
+EARLY_DRIVER_MODULE(ebus, nexus, ebus_nexus_driver, ebus_devclass, 0, 0,
+    BUS_PASS_BUS + 1);
+MODULE_DEPEND(ebus, nexus, 1, 1, 1);
+
+static device_method_t ebus_pci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ebus_pci_probe),
+	DEVMETHOD(device_attach,	ebus_pci_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	ebus_print_child),
+	DEVMETHOD(bus_probe_nomatch,	ebus_probe_nomatch),
+	DEVMETHOD(bus_alloc_resource,	ebus_alloc_resource),
+	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_release_resource,	ebus_release_resource),
+	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	DEVMETHOD(bus_get_resource_list, ebus_get_resource_list),
+	DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	ebus_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	DEVMETHOD_END
+};
+
+static driver_t ebus_pci_driver = {
+	"ebus",
+	ebus_pci_methods,
+	sizeof(struct ebus_softc),
+};
+
+EARLY_DRIVER_MODULE(ebus, pci, ebus_pci_driver, ebus_devclass, 0, 0,
+    BUS_PASS_BUS);
+MODULE_DEPEND(ebus, pci, 1, 1, 1);
+MODULE_VERSION(ebus, 1);
+
+static int
+ebus_nexus_probe(device_t dev)
+{
+	const char* compat;
+
+	compat = ofw_bus_get_compat(dev);
+	if (compat != NULL && strcmp(ofw_bus_get_name(dev), "ebus") == 0 &&
+	    strcmp(compat, "jbus-ebus") == 0) {
+		device_set_desc(dev, "JBus-EBus bridge");
+		return (BUS_PROBE_GENERIC);
+	}
+	return (ENXIO);
+}
+
+static int
+ebus_pci_probe(device_t dev)
+{
+
+	if (pci_get_class(dev) != PCIC_BRIDGE ||
+	    pci_get_vendor(dev) != 0x108e ||
+	    strcmp(ofw_bus_get_name(dev), "ebus") != 0)
+		return (ENXIO);
+
+	if (pci_get_device(dev) == 0x1000)
+		device_set_desc(dev, "PCI-EBus2 bridge");
+	else if (pci_get_device(dev) == 0x1100)
+		device_set_desc(dev, "PCI-EBus3 bridge");
+	else
+		return (ENXIO);
+	return (BUS_PROBE_GENERIC);
+}
+
+static int
+ebus_nexus_attach(device_t dev)
+{
+	struct ebus_softc *sc;
+	phandle_t node;
+
+	sc = device_get_softc(dev);
+	node = ofw_bus_get_node(dev);
+
+#ifndef SUN4V
+	if (OF_getprop(node, "portid", &sc->sc_ign,
+	    sizeof(sc->sc_ign)) == -1) {
+		device_printf(dev, "could not determine IGN");
+		return (ENXIO);
+	}
+#endif
+
+	sc->sc_nrange = OF_getprop_alloc(node, "ranges",
+	    sizeof(struct ebus_nexus_ranges), &sc->sc_range);
+	if (sc->sc_nrange == -1) {
+		device_printf(dev, "could not get ranges property\n");
+		return (ENXIO);
+	}
+	return (ebus_attach(dev, sc, node));
+}
+
+static int
+ebus_pci_attach(device_t dev)
+{
+	struct ebus_softc *sc;
+	struct ebus_rinfo *eri;
+	struct resource *res;
+	struct isa_ranges *range;
+	phandle_t node;
+	int i, rnum, rid;
+
+	sc = device_get_softc(dev);
+	sc->sc_flags |= EBUS_PCI;
+
+	pci_write_config(dev, PCIR_COMMAND,
+	    pci_read_config(dev, PCIR_COMMAND, 2) | PCIM_CMD_SERRESPEN |
+	    PCIM_CMD_PERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN, 2);
+	pci_write_config(dev, PCIR_CACHELNSZ, 16 /* 64 bytes */, 1);
+	pci_write_config(dev, PCIR_LATTIMER, 64 /* 64 PCI cycles */, 1);
+
+	node = ofw_bus_get_node(dev);
+	sc->sc_nrange = OF_getprop_alloc(node, "ranges",
+	    sizeof(struct isa_ranges), &sc->sc_range);
+	if (sc->sc_nrange == -1) {
+		device_printf(dev, "could not get ranges property\n");
+		return (ENXIO);
+	}
+
+	sc->sc_rinfo = malloc(sizeof(*sc->sc_rinfo) * sc->sc_nrange, M_DEVBUF,
+	    M_WAITOK | M_ZERO);
+
+	/* For every range, there must be a matching resource. */
+	for (rnum = 0; rnum < sc->sc_nrange; rnum++) {
+		eri = &sc->sc_rinfo[rnum];
+		range = &((struct isa_ranges *)sc->sc_range)[rnum];
+		eri->eri_rtype = ofw_isa_range_restype(range);
+		rid = PCIR_BAR(rnum);
+		res = bus_alloc_resource_any(dev, eri->eri_rtype, &rid,
+		    RF_ACTIVE);
+		if (res == NULL) {
+			device_printf(dev,
+			    "could not allocate range resource %d\n", rnum);
+			goto fail;
+		}
+		if (rman_get_start(res) != ISA_RANGE_PHYS(range)) {
+			device_printf(dev,
+			    "mismatch in start of range %d (0x%lx/0x%lx)\n",
+			    rnum, rman_get_start(res), ISA_RANGE_PHYS(range));
+			goto fail;
+		}
+		if (rman_get_size(res) != range->size) {
+			device_printf(dev,
+			    "mismatch in size of range %d (0x%lx/0x%x)\n",
+			    rnum, rman_get_size(res), range->size);
+			goto fail;
+		}
+		eri->eri_res = res;
+		eri->eri_rman.rm_type = RMAN_ARRAY;
+		eri->eri_rman.rm_descr = "EBus range";
+		if (rman_init_from_resource(&eri->eri_rman, res) != 0) {
+			device_printf(dev,
+			    "could not initialize rman for range %d", rnum);
+			goto fail;
+		}
+	}
+	return (ebus_attach(dev, sc, node));
+
+ fail:
+	for (i = rnum; i >= 0; i--) {
+		eri = &sc->sc_rinfo[i];
+		if (i < rnum)
+			rman_fini(&eri->eri_rman);
+		if (eri->eri_res != 0) {
+			bus_release_resource(dev, eri->eri_rtype,
+			    PCIR_BAR(rnum), eri->eri_res);
+		}
+	}
+	free(sc->sc_rinfo, M_DEVBUF);
+	free(sc->sc_range, M_OFWPROP);
+	return (ENXIO);
+}
+
+static int
+ebus_attach(device_t dev, struct ebus_softc *sc, phandle_t node)
+{
+	struct ebus_devinfo *edi;
+	device_t cdev;
+
+	ofw_bus_setup_iinfo(node, &sc->sc_iinfo, sizeof(ofw_isa_intr_t));
+
+	/*
+	 * Now attach our children.
+	 */
+	for (node = OF_child(node); node > 0; node = OF_peer(node)) {
+		if ((edi = ebus_setup_dinfo(dev, sc, node)) == NULL)
+			continue;
+		if ((cdev = device_add_child(dev, NULL, -1)) == NULL) {
+			device_printf(dev, "<%s>: device_add_child failed\n",
+			    edi->edi_obdinfo.obd_name);
+			ebus_destroy_dinfo(edi);
+			continue;
+		}
+		device_set_ivars(cdev, edi);
+	}
+	return (bus_generic_attach(dev));
+}
+
+static int
+ebus_print_child(device_t dev, device_t child)
+{
+	int retval;
+
+	retval = bus_print_child_header(dev, child);
+	retval += ebus_print_res(device_get_ivars(child));
+	retval += bus_print_child_footer(dev, child);
+	return (retval);
+}
+
+static void
+ebus_probe_nomatch(device_t dev, device_t child)
+{
+
+	device_printf(dev, "<%s>", ofw_bus_get_name(child));
+	ebus_print_res(device_get_ivars(child));
+	printf(" (no driver attached)\n");
+}
+
+static struct resource *
+ebus_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct ebus_softc *sc;
+	struct resource_list *rl;
+	struct resource_list_entry *rle = NULL;
+	struct resource *res;
+	struct ebus_rinfo *eri;
+	struct ebus_nexus_ranges *enr;
+	uint64_t cend, cstart, offset;
+	int i, isdefault, passthrough, ridx;
+
+	isdefault = (start == 0UL && end == ~0UL);
+	passthrough = (device_get_parent(child) != bus);
+	sc = device_get_softc(bus);
+	rl = BUS_GET_RESOURCE_LIST(bus, child);
+	switch (type) {
+	case SYS_RES_MEMORY:
+		KASSERT(!(isdefault && passthrough),
+		    ("%s: passthrough of default allocation", __func__));
+		if (!passthrough) {
+			rle = resource_list_find(rl, type, *rid);
+			if (rle == NULL)
+				return (NULL);
+			KASSERT(rle->res == NULL,
+			    ("%s: resource entry is busy", __func__));
+			if (isdefault) {
+				start = rle->start;
+				count = ulmax(count, rle->count);
+				end = ulmax(rle->end, start + count - 1);
+			}
+		}
+
+		res = NULL;
+		if ((sc->sc_flags & EBUS_PCI) != 0) {
+			/*
+			 * Map EBus ranges to PCI ranges.  This may include
+			 * changing the allocation type.
+			 */
+			type = ofw_isa_range_map(sc->sc_range, sc->sc_nrange,
+			    &start, &end, &ridx);
+			eri = &sc->sc_rinfo[ridx];
+			res = rman_reserve_resource(&eri->eri_rman, start,
+			    end, count, flags & ~RF_ACTIVE, child);
+			if (res == NULL)
+				return (NULL);
+			rman_set_rid(res, *rid);
+			if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(
+			    child, type, *rid, res) != 0) {
+				rman_release_resource(res);
+				return (NULL);
+			}
+		} else {
+			/* Map EBus ranges to nexus ranges. */
+			for (i = 0; i < sc->sc_nrange; i++) {
+				enr = &((struct ebus_nexus_ranges *)
+				    sc->sc_range)[i];
+				cstart = (((uint64_t)enr->child_hi) << 32) |
+				    enr->child_lo;
+				cend = cstart + enr->size - 1;
+				if (start >= cstart && end <= cend) {
+					offset =
+					    (((uint64_t)enr->phys_hi) << 32) |
+					    enr->phys_lo;
+					start += offset - cstart;
+					end += offset - cstart;
+					res = bus_generic_alloc_resource(bus,
+					    child, type, rid, start, end,
+					    count, flags);
+					break;
+				}
+			}
+		}
+		if (!passthrough)
+			rle->res = res;
+		return (res);
+	case SYS_RES_IRQ:
+		return (resource_list_alloc(rl, bus, child, type, rid, start,
+		    end, count, flags));
+	}
+	return (NULL);
+}
+
+static int
+ebus_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *res)
+{
+	struct ebus_softc *sc;
+	struct ebus_rinfo *eri;
+	bus_space_tag_t bt;
+	bus_space_handle_t bh;
+	int i, rv;
+
+	sc = device_get_softc(bus);
+	if ((sc->sc_flags & EBUS_PCI) != 0 && type != SYS_RES_IRQ) {
+		for (i = 0; i < sc->sc_nrange; i++) {
+			eri = &sc->sc_rinfo[i];
+			if (rman_is_region_manager(res, &eri->eri_rman) != 0) {
+				bt = rman_get_bustag(eri->eri_res);
+				rv = bus_space_subregion(bt,
+				    rman_get_bushandle(eri->eri_res),
+				    rman_get_start(res) -
+				    rman_get_start(eri->eri_res),
+				    rman_get_size(res), &bh);
+				if (rv != 0)
+					return (rv);
+				rman_set_bustag(res, bt);
+				rman_set_bushandle(res, bh);
+				return (rman_activate_resource(res));
+			}
+		}
+		return (EINVAL);
+	}
+	return (bus_generic_activate_resource(bus, child, type, rid, res));
+}
+
+static int
+ebus_adjust_resource(device_t bus __unused, device_t child __unused,
+    int type __unused, struct resource *res __unused, u_long start __unused,
+    u_long end __unused)
+{
+
+	return (ENXIO);
+}
+
+static int
+ebus_release_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *res)
+{
+	struct ebus_softc *sc;
+	struct resource_list *rl;
+	struct resource_list_entry *rle;
+	int passthrough, rv;
+
+	passthrough = (device_get_parent(child) != bus);
+	rl = BUS_GET_RESOURCE_LIST(bus, child);
+	sc = device_get_softc(bus);
+	if ((sc->sc_flags & EBUS_PCI) != 0 && type != SYS_RES_IRQ) {
+		if ((rman_get_flags(res) & RF_ACTIVE) != 0 ){
+			rv = bus_deactivate_resource(child, type, rid, res);
+			if (rv != 0)
+				return (rv);
+		}
+		rv = rman_release_resource(res);
+		if (rv != 0)
+			return (rv);
+		if (!passthrough) {
+			rle = resource_list_find(rl, type, rid);
+			KASSERT(rle != NULL,
+			    ("%s: resource entry not found!", __func__));
+			KASSERT(rle->res != NULL,
+			   ("%s: resource entry is not busy", __func__));
+			rle->res = NULL;
+		}
+		return (0);
+	}
+	return (resource_list_release(rl, bus, child, type, rid, res));
+}
+
+static int
+ebus_setup_intr(device_t dev, device_t child, struct resource *ires,
+    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
+    void **cookiep)
+{
+#ifndef SUN4V
+	struct ebus_softc *sc;
+	u_long vec;
+
+	sc = device_get_softc(dev);
+	if ((sc->sc_flags & EBUS_PCI) == 0) {
+		/*
+		 * Make sure the vector is fully specified.  This isn't
+		 * necessarily the case with the PCI variant.
+		 */
+		vec = rman_get_start(ires);
+		if (INTIGN(vec) != sc->sc_ign) {
+			device_printf(dev,
+			    "invalid interrupt vector 0x%lx\n", vec);
+			return (EINVAL);
+		}
+
+		/*
+		 * As we rely on the interrupt controllers of the
+		 * accompanying PCI-Express bridge ensure at least
+		 * something is registered for this vector.
+		 */
+		if (intr_vectors[vec].iv_ic == NULL) {
+			device_printf(dev,
+			    "invalid interrupt controller for vector 0x%lx\n",
+			    vec);
+			return (EINVAL);
+		}
+	}
+#endif
+	return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr,
+	    arg, cookiep));
+}
+
+static struct resource_list *
+ebus_get_resource_list(device_t dev, device_t child)
+{
+	struct ebus_devinfo *edi;
+
+	edi = device_get_ivars(child);
+	return (&edi->edi_rl);
+}
+
+static const struct ofw_bus_devinfo *
+ebus_get_devinfo(device_t bus, device_t dev)
+{
+	struct ebus_devinfo *edi;
+
+	edi = device_get_ivars(dev);
+	return (&edi->edi_obdinfo);
+}
+
+static struct ebus_devinfo *
+ebus_setup_dinfo(device_t dev, struct ebus_softc *sc, phandle_t node)
+{
+	struct isa_regs reg, *regs;
+	ofw_isa_intr_t intr, *intrs;
+	struct ebus_devinfo *edi;
+	uint64_t start;
+	uint32_t rintr;
+	int i, nintr, nreg, rv;
+
+	edi = malloc(sizeof(*edi), M_DEVBUF, M_ZERO | M_WAITOK);
+	if (ofw_bus_gen_setup_devinfo(&edi->edi_obdinfo, node) != 0) {
+		free(edi, M_DEVBUF);
+		return (NULL);
+	}
+	resource_list_init(&edi->edi_rl);
+	nreg = OF_getprop_alloc(node, "reg", sizeof(*regs), (void **)&regs);
+	if (nreg == -1) {
+		device_printf(dev, "<%s>: incomplete\n",
+		    edi->edi_obdinfo.obd_name);
+		ebus_destroy_dinfo(edi);
+		return (NULL);
+	}
+	for (i = 0; i < nreg; i++) {
+		start = ISA_REG_PHYS(regs + i);
+		(void)resource_list_add(&edi->edi_rl, SYS_RES_MEMORY, i,
+		    start, start + regs[i].size - 1, regs[i].size);
+	}
+	free(regs, M_OFWPROP);
+
+	nintr = OF_getprop_alloc(node, "interrupts",  sizeof(*intrs),
+	    (void **)&intrs);
+	if (nintr == -1)
+		return (edi);
+	for (i = 0; i < nintr; i++) {
+		rv = 0;
+		if ((sc->sc_flags & EBUS_PCI) != 0) {
+			rintr = ofw_isa_route_intr(dev, node, &sc->sc_iinfo,
+			    intrs[i]);
+		} else {
+			intr = intrs[i];
+			rv = ofw_bus_lookup_imap(node, &sc->sc_iinfo, &reg,
+			    sizeof(reg), &intr, sizeof(intr), &rintr,
+			    sizeof(rintr), NULL);
+#ifndef SUN4V
+			if (rv != 0)
+				rintr = INTMAP_VEC(sc->sc_ign, rintr);
+#endif
+		}
+		if ((sc->sc_flags & EBUS_PCI) == 0 ? rv == 0 :
+		    rintr == PCI_INVALID_IRQ) {
+			device_printf(dev,
+			    "<%s>: could not map EBus interrupt %d\n",
+			    edi->edi_obdinfo.obd_name, intrs[i]);
+			continue;
+		}
+		(void)resource_list_add(&edi->edi_rl, SYS_RES_IRQ, i, rintr,
+		    rintr, 1);
+	}
+	free(intrs, M_OFWPROP);
+	return (edi);
+}
+
+static void
+ebus_destroy_dinfo(struct ebus_devinfo *edi)
+{
+
+	resource_list_free(&edi->edi_rl);
+	ofw_bus_gen_destroy_devinfo(&edi->edi_obdinfo);
+	free(edi, M_DEVBUF);
+}
+
+static int
+ebus_print_res(struct ebus_devinfo *edi)
+{
+	int retval;
+
+	retval = 0;
+	retval += resource_list_print_type(&edi->edi_rl, "addr", SYS_RES_MEMORY,
+	    "%#lx");
+	retval += resource_list_print_type(&edi->edi_rl, "irq", SYS_RES_IRQ,
+	    "%ld");
+	return (retval);
+}


Property changes on: trunk/sys/sparc64/ebus/ebus.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/ebus/ebusreg.h
===================================================================
--- trunk/sys/sparc64/ebus/ebusreg.h	                        (rev 0)
+++ trunk/sys/sparc64/ebus/ebusreg.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,90 @@
+/* $MidnightBSD$ */
+/*	$FreeBSD: stable/10/sys/sparc64/ebus/ebusreg.h 219567 2011-03-12 14:33:32Z marius $	*/
+/*	$OpenBSD: ebusreg.h,v 1.4 2001/10/01 18:08:04 jason Exp $	*/
+/*	$NetBSD: ebusreg.h,v 1.8 2008/05/29 14:51:27 mrg Exp $	*/
+
+/*-
+ * Copyright (c) 1999 Matthew R. Green
+ * 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 ``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.
+ *
+ */
+
+/*
+ * UltraSPARC `ebus'
+ *
+ * The `ebus' bus is designed to plug traditional PC-ISA devices into
+ * an SPARC system with as few costs as possible, without sacrificing
+ * to performance.  Typically, it is implemented in the PCIO IC from
+ * SME, which also implements a `hme-compatible' PCI network device
+ * (`network').  The ebus has 4 DMA channels, similar to the DMA seen
+ * in the ESP SCSI DMA.
+ *
+ * Typical UltraSPARC systems have a NatSemi SuperIO IC to provide
+ * serial ports for the keyboard and mouse (`se'), floppy disk
+ * controller (`fdthree'), parallel port controller (`bpp') connected
+ * to the ebus, and a PCI-IDE controller (connected directly to the
+ * PCI bus, of course), as well as a Siemens Nixdorf SAB82532 dual
+ * channel serial controller (`su' providing ttya and ttyb), an MK48T59
+ * EEPROM/clock controller (also where the idprom, including the
+ * ethernet address, is located), the audio system (`SUNW,CS4231', same
+ * as other UltraSPARC and some SPARC systems), and other various
+ * internal devices found on traditional SPARC systems such as the
+ * `power', `flashprom', etc., devices.
+ *
+ * The ebus uses an interrupt mapping scheme similar to PCI, though
+ * the actual structures are different.
+ */
+
+/* EBUS dma registers */
+#define	EBDMA_DCSR		0x0		/* control/status */
+#define	EBDMA_DADDR		0x4		/* DMA address */
+#define	EBDMA_DCNT		0x8		/* DMA count */
+
+/* EBUS DMA control/status (EBDMA_DCSR) */
+#define	EBDCSR_INT		0x00000001	/* interrupt pending */
+#define	EBDCSR_ERR		0x00000002	/* error pending */
+#define	EBDCSR_DRAIN		0x00000004	/* drain */
+#define	EBDCSR_INTEN		0x00000010	/* interrupt enable */
+#define	EBDCSR_RESET		0x00000080	/* reset */
+#define	EBDCSR_WRITE		0x00000100	/* write */
+#define	EBDCSR_DMAEN		0x00000200	/* dma enable */
+#define	EBDCSR_CYC		0x00000400	/* cyc pending */
+#define	EBDCSR_DIAGRD		0x00000800	/* diagnostic read done */
+#define	EBDCSR_DIAGWR		0x00001000	/* diagnostic write done */
+#define	EBDCSR_CNTEN		0x00002000	/* count enable */
+#define	EBDCSR_TC		0x00004000	/* terminal count */
+#define	EBDCSR_CSRDRNDIS	0x00010000	/* disable csr drain */
+#define	EBDCSR_BURSTMASK	0x000c0000	/* burst size mask */
+#define	EBDCSR_BURST_1		0x00080000	/* burst 1 */
+#define	EBDCSR_BURST_4		0x00000000	/* burst 4 */
+#define	EBDCSR_BURST_8		0x00040000	/* burst 8 */
+#define	EBDCSR_BURST_16		0x000c0000	/* burst 16 */
+#define	EBDCSR_DIAGEN		0x00100000	/* enable diagnostics */
+#define	EBDCSR_ERRDIS		0x00400000	/* disable error pending */
+#define	EBDCSR_TCIDIS		0x00800000	/* disable TCI */
+#define	EBDCSR_NEXTEN		0x01000000	/* enable next */
+#define	EBDCSR_DMAON		0x02000000	/* dma on */
+#define	EBDCSR_A_LOADED		0x04000000	/* address loaded */
+#define	EBDCSR_NA_LOADED	0x08000000	/* next address loaded */
+#define	EBDCSR_DEVMASK		0xf0000000	/* device id mask */


Property changes on: trunk/sys/sparc64/ebus/ebusreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/ebus/epic.c
===================================================================
--- trunk/sys/sparc64/ebus/epic.c	                        (rev 0)
+++ trunk/sys/sparc64/ebus/epic.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,217 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/ebus/epic.c 227848 2011-11-22 21:55:40Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <dev/led/led.h>
+#include <dev/ofw/ofw_bus.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#define	EPIC_DELAY			10000
+
+#define	EPIC_NREG			1
+#define	EPIC_FW_LED			0
+
+#define	EPIC_FW_LED_DATA		0x40
+#define	EPIC_FW_LED_ADDR		0x41
+#define	EPIC_FW_LED_WRITE_MASK		0x80
+
+#define	EPIC_FW_VERSION			0x05
+#define	EPIC_LED_STATE0			0x06
+
+#define	EPIC_LED_ALERT_MASK		0x0c
+#define	EPIC_LED_ALERT_OFF		0x00
+#define	EPIC_LED_ALERT_ON		0x04
+
+#define	EPIC_LED_POWER_MASK		0x30
+#define	EPIC_LED_POWER_OFF		0x00
+#define	EPIC_LED_POWER_ON		0x10
+#define	EPIC_LED_POWER_SB_BLINK		0x20
+#define	EPIC_LED_POWER_FAST_BLINK	0x30
+
+static struct resource_spec epic_res_spec[] = {
+	{ SYS_RES_MEMORY, EPIC_FW_LED, RF_ACTIVE },
+	{ -1, 0 }
+};
+
+struct epic_softc {
+	struct mtx		sc_mtx;
+	struct resource		*sc_res[EPIC_NREG];
+	struct cdev		*sc_led_dev_alert;
+	struct cdev		*sc_led_dev_power;
+};
+
+#define	EPIC_FW_LED_READ(sc, off) ({					\
+	uint8_t	__val;							\
+	bus_write_1((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_ADDR, (off));\
+	bus_barrier((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_ADDR, 1,	\
+	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);		\
+	DELAY(EPIC_DELAY);						\
+	__val = bus_read_1((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_DATA);\
+	bus_barrier((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_DATA, 1,	\
+	    BUS_SPACE_BARRIER_READ);					\
+	DELAY(EPIC_DELAY);						\
+	__val;								\
+})
+
+#define	EPIC_FW_LED_WRITE(sc, off, mask, val) do {			\
+	bus_write_1((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_ADDR, (off));\
+	bus_barrier((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_ADDR, 1,	\
+	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);		\
+	DELAY(EPIC_DELAY);						\
+	bus_write_1((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_WRITE_MASK,	\
+	    (mask));							\
+	bus_barrier((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_WRITE_MASK,	\
+	    1, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);	\
+	DELAY(EPIC_DELAY);						\
+	bus_write_1((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_DATA, (val));\
+	bus_barrier((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_DATA, 1,	\
+	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);		\
+	DELAY(EPIC_DELAY);						\
+} while (0)
+
+#define	EPIC_LOCK_INIT(sc)						\
+	mtx_init(&(sc)->sc_mtx, "epic mtx", NULL, MTX_DEF)
+#define	EPIC_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
+#define	EPIC_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
+#define	EPIC_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
+
+static device_probe_t epic_probe;
+static device_attach_t epic_attach;
+static device_detach_t epic_detach;
+
+static void epic_led_alert(void *arg, int onoff);
+static void epic_led_power(void *arg, int onoff);
+
+static device_method_t epic_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		epic_probe),
+	DEVMETHOD(device_attach,	epic_attach),
+	DEVMETHOD(device_detach,	epic_detach),
+
+	DEVMETHOD_END
+};
+
+static devclass_t epic_devclass;
+
+DEFINE_CLASS_0(epic, epic_driver, epic_methods,
+    sizeof(struct epic_softc));
+DRIVER_MODULE(epic, ebus, epic_driver, epic_devclass, 0, 0);
+
+static int
+epic_probe(device_t dev)
+{
+	const char* compat;
+
+	compat = ofw_bus_get_compat(dev);
+	if (compat != NULL && strcmp(ofw_bus_get_name(dev),
+	    "env-monitor") == 0 && strcmp(compat, "epic") == 0) {
+		device_set_desc(dev, "Sun Fire V215/V245 LEDs");
+		return (BUS_PROBE_DEFAULT);
+	}
+	return (ENXIO);
+}
+
+static int
+epic_attach(device_t dev)
+{
+	struct epic_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (bus_alloc_resources(dev, epic_res_spec, sc->sc_res)) {
+		device_printf(dev, "failed to allocate resources\n");
+		bus_release_resources(dev, epic_res_spec, sc->sc_res);
+		return (ENXIO);
+	}
+
+	EPIC_LOCK_INIT(sc);
+
+	if (bootverbose)
+		device_printf(dev, "version 0x%x\n",
+		    EPIC_FW_LED_READ(sc, EPIC_FW_VERSION));
+
+	sc->sc_led_dev_alert = led_create(epic_led_alert, sc, "alert");
+	sc->sc_led_dev_power = led_create(epic_led_power, sc, "power");
+
+	return (0);
+}
+
+static int
+epic_detach(device_t dev)
+{
+	struct epic_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	led_destroy(sc->sc_led_dev_alert);
+	led_destroy(sc->sc_led_dev_power);
+
+	bus_release_resources(dev, epic_res_spec, sc->sc_res);
+
+	EPIC_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+static void
+epic_led_alert(void *arg, int onoff)
+{
+	struct epic_softc *sc;
+
+	sc = (struct epic_softc *)arg;
+
+	EPIC_LOCK(sc);
+	EPIC_FW_LED_WRITE(sc, EPIC_LED_STATE0, EPIC_LED_ALERT_MASK,
+	    onoff ? EPIC_LED_ALERT_ON : EPIC_LED_ALERT_OFF);
+	EPIC_UNLOCK(sc);
+}
+
+static void
+epic_led_power(void *arg, int onoff)
+{
+	struct epic_softc *sc;
+
+	sc = (struct epic_softc *)arg;
+
+	EPIC_LOCK(sc);
+	EPIC_FW_LED_WRITE(sc, EPIC_LED_STATE0, EPIC_LED_POWER_MASK,
+	    onoff ? EPIC_LED_POWER_ON : EPIC_LED_POWER_OFF);
+	EPIC_UNLOCK(sc);
+}


Property changes on: trunk/sys/sparc64/ebus/epic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/fhc/clkbrd.c
===================================================================
--- trunk/sys/sparc64/fhc/clkbrd.c	                        (rev 0)
+++ trunk/sys/sparc64/fhc/clkbrd.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,213 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Jason L. Wright (jason at thought.net)
+ * Copyright (c) 2005 Marius Strobl <marius at 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, 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.
+ *
+ *	from: OpenBSD: clkbrd.c,v 1.5 2004/10/01 18:18:49 jason Exp
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/fhc/clkbrd.c 157225 2006-03-28 19:46:48Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <dev/led/led.h>
+#include <dev/ofw/ofw_bus.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <sparc64/fhc/clkbrdreg.h>
+
+#define	CLKBRD_NREG	3
+
+#define	CLKBRD_CF	0
+#define	CLKBRD_CLK	1
+#define	CLKBRD_CLKVER	2
+
+struct clkbrd_softc {
+	struct device		*sc_dev;
+	struct resource		*sc_res[CLKBRD_NREG];
+	int			sc_rid[CLKBRD_NREG];
+	bus_space_tag_t		sc_bt[CLKBRD_NREG];
+	bus_space_handle_t	sc_bh[CLKBRD_NREG];
+	uint8_t			sc_clk_ctrl;
+	struct cdev		*sc_led_dev;
+	int			sc_flags;
+#define	CLKBRD_HAS_CLKVER	(1 << 0)
+};
+
+static devclass_t clkbrd_devclass;
+
+static device_probe_t clkbrd_probe;
+static device_attach_t clkbrd_attach;
+static device_detach_t clkbrd_detach;
+
+static void clkbrd_free_resources(struct clkbrd_softc *);
+static void clkbrd_led_func(void *, int);
+
+static device_method_t clkbrd_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		clkbrd_probe),
+	DEVMETHOD(device_attach,	clkbrd_attach),
+	DEVMETHOD(device_detach,	clkbrd_detach),
+
+        { 0, 0 }
+};
+
+static driver_t clkbrd_driver = {
+        "clkbrd",
+        clkbrd_methods,
+        sizeof(struct clkbrd_softc),
+};
+
+DRIVER_MODULE(clkbrd, fhc, clkbrd_driver, clkbrd_devclass, 0, 0);
+
+static int
+clkbrd_probe(device_t dev)
+{
+
+	if (strcmp(ofw_bus_get_name(dev), "clock-board") == 0) {
+		device_set_desc(dev, "Clock Board");
+		return (0);
+	}
+	return (ENXIO);
+}
+
+static int
+clkbrd_attach(device_t dev)
+{
+	struct clkbrd_softc *sc;
+	int i, slots;
+	uint8_t r;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	for (i = CLKBRD_CF; i <= CLKBRD_CLKVER; i++) {
+		sc->sc_rid[i] = i;
+		sc->sc_res[i] = bus_alloc_resource_any(sc->sc_dev,
+		    SYS_RES_MEMORY, &sc->sc_rid[i], RF_ACTIVE);
+		if (sc->sc_res[i] == NULL) {
+			if (i != CLKBRD_CLKVER) {
+				device_printf(sc->sc_dev,
+				    "could not allocate resource %d\n", i);
+				goto fail;
+			}
+			continue;
+		}
+		sc->sc_bt[i] = rman_get_bustag(sc->sc_res[i]);
+		sc->sc_bh[i] = rman_get_bushandle(sc->sc_res[i]);
+		if (i == CLKBRD_CLKVER)
+			sc->sc_flags |= CLKBRD_HAS_CLKVER;
+	}
+
+	slots = 4;
+	r = bus_space_read_1(sc->sc_bt[CLKBRD_CLK], sc->sc_bh[CLKBRD_CLK],
+	    CLK_STS1);
+	switch (r & CLK_STS1_SLOTS_MASK) {
+	case CLK_STS1_SLOTS_16:
+		slots = 16;
+		break;
+	case CLK_STS1_SLOTS_8:
+		slots = 8;
+		break;
+	case CLK_STS1_SLOTS_4:
+		if (sc->sc_flags & CLKBRD_HAS_CLKVER) {
+			r = bus_space_read_1(sc->sc_bt[CLKBRD_CLKVER],
+			    sc->sc_bh[CLKBRD_CLKVER], CLKVER_SLOTS);
+			if (r != 0 &&
+			    (r & CLKVER_SLOTS_MASK) == CLKVER_SLOTS_PLUS)
+				slots = 5;
+		}
+	}
+
+	device_printf(sc->sc_dev, "Sun Enterprise Exx00 machine: %d slots\n",
+	    slots);
+
+	sc->sc_clk_ctrl = bus_space_read_1(sc->sc_bt[CLKBRD_CLK],
+	    sc->sc_bh[CLKBRD_CLK], CLK_CTRL);
+	sc->sc_led_dev = led_create(clkbrd_led_func, sc, "clockboard");
+
+	return (0);
+
+ fail:
+	clkbrd_free_resources(sc);
+
+	return (ENXIO);
+}
+
+static int
+clkbrd_detach(device_t dev)
+{
+	struct clkbrd_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	led_destroy(sc->sc_led_dev);
+	bus_space_write_1(sc->sc_bt[CLKBRD_CLK], sc->sc_bh[CLKBRD_CLK],
+	    CLK_CTRL, sc->sc_clk_ctrl);
+	bus_space_read_1(sc->sc_bt[CLKBRD_CLK], sc->sc_bh[CLKBRD_CLK],
+	    CLK_CTRL);
+	clkbrd_free_resources(sc);
+
+	return (0);
+}
+
+static void
+clkbrd_free_resources(struct clkbrd_softc *sc)
+{
+	int i;
+
+	for (i = CLKBRD_CF; i <= CLKBRD_CLKVER; i++)
+		if (sc->sc_res[i] != NULL)
+			bus_release_resource(sc->sc_dev, SYS_RES_MEMORY,
+			    sc->sc_rid[i], sc->sc_res[i]);
+}
+
+static void
+clkbrd_led_func(void *arg, int onoff)
+{
+	struct clkbrd_softc *sc;
+	uint8_t r;
+
+	sc = (struct clkbrd_softc *)arg;
+
+	r = bus_space_read_1(sc->sc_bt[CLKBRD_CLK], sc->sc_bh[CLKBRD_CLK],
+	    CLK_CTRL);
+	if (onoff)
+		r |= CLK_CTRL_RLED;
+	else
+		r &= ~CLK_CTRL_RLED;
+	bus_space_write_1(sc->sc_bt[CLKBRD_CLK], sc->sc_bh[CLKBRD_CLK],
+	    CLK_CTRL, r);
+	bus_space_read_1(sc->sc_bt[CLKBRD_CLK], sc->sc_bh[CLKBRD_CLK],
+	    CLK_CTRL);
+}


Property changes on: trunk/sys/sparc64/fhc/clkbrd.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/fhc/clkbrdreg.h
===================================================================
--- trunk/sys/sparc64/fhc/clkbrdreg.h	                        (rev 0)
+++ trunk/sys/sparc64/fhc/clkbrdreg.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,98 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Jason L. Wright (jason at thought.net)
+ * Copyright (c) 2006 Marius Strobl <marius at 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, 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.
+ *
+ *	from: OpenBSD: clkbrdreg.h,v 1.2 2004/10/01 15:36:30 jason Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/fhc/clkbrdreg.h 157225 2006-03-28 19:46:48Z marius $
+ */
+
+#ifndef _SPARC64_FHC_CLKBRDREG_H_
+#define	_SPARC64_FHC_CLKBRDREG_H_
+
+/* register bank 0 */
+#define	CLK_CF_REG2		0x20	/* clock frequency register 2 */
+#define	 CLK_CF_REG2_REN_RCONS	0x80	/* reset enable: remote console */
+#define	 CLK_CF_REG2_REN_GEN	0x40	/* reset enable: frequency change */
+#define	 CLK_CF_REG2_REN_WDOG	0x20	/* reset enable: watchdog */
+#define	 CLK_CF_REG2_DIV1	0x10	/* CPU module divisor bit 1 */
+#define	 CLK_CF_REG2_RANGE	0x0c	/* clock range */
+#define	 CLK_CF_REG2_DIV0	0x02	/* CPU module divisor bit 0 */
+#define	 CLK_CF_REG2_FREQ8	0x01	/* frequency bit 8 */
+
+/* register bank 1 */
+#define	CLK_CTRL		0x00	/* system control register */
+#define	 CLK_CTRL_IEN_FAN	0x80	/* intr enable: fan failure */
+#define	 CLK_CTRL_IEN_DC	0x40	/* intr enable: power supply DC */
+#define	 CLK_CTRL_IEN_AC	0x20	/* intr enable: AC power */
+#define	 CLK_CTRL_IEN_BRD	0x10	/* intr enable: board insert */
+#define	 CLK_CTRL_POFF		0x08	/* turn off system power */
+#define	 CLK_CTRL_LLED		0x04	/* left led (reversed) */
+#define	 CLK_CTRL_MLED		0x02	/* middle led */
+#define	 CLK_CTRL_RLED		0x01	/* right led */
+#define	CLK_STS1		0x10	/* system status register 1 */
+#define	 CLK_STS1_SLOTS_MASK	0xc0	/* system status 1 slots mask */
+#define	 CLK_STS1_SLOTS_16	0x40	/* 16 slots */
+#define	 CLK_STS1_SLOTS_8	0xc0	/* 8 slots */
+#define	 CLK_STS1_SLOTS_4	0x80	/* 4 slots */
+#define	 CLK_STS1_SLOTS_TESTBED	0x00	/* test machine */
+#define	 CLK_STS1_SECURE	0x20	/* key in position secure (reversed) */
+#define	 CLK_STS1_FAN		0x10	/* fan tray present (reversed) */
+#define	 CLK_STS1_BRD		0x08	/* board inserted (reversed) */
+#define	 CLK_STS1_PS0		0x04	/* power supply 0 present (reversed) */
+#define	 CLK_STS1_RST_WDOG	0x02	/* rst by: watchdog (reversed) */
+#define	 CLK_STS1_RST_GEN	0x01	/* rst by: freq change (reversed) */
+#define	CLK_STS2		0x20	/* system status register 2 */
+#define	 CLK_STS2_RST_RCONS	0x80	/* rst by: remote console (reversed) */
+#define	 CLK_STS2_OK_PS0	0x40	/* ok: power supply 0 */
+#define	 CLK_STS2_OK_33V	0x20	/* ok: 3.3V on clock board */
+#define	 CLK_STS2_OK_50V	0x10	/* ok: 5.0V on clock board */
+#define	 CLK_STS2_FAIL_AC	0x08	/* failed: AC power */
+#define	 CLK_STS2_FAIL_FAN	0x04	/* failed: rack fans */
+#define	 CLK_STS2_OK_ACFAN	0x02	/* ok: 4 AC box fans */
+#define	 CLK_STS2_OK_KEYFAN	0x01	/* ok: keyswitch fans */
+#define	CLK_PSTS1		0x30	/* power supply 1 status register */
+#define	 CLK_PSTS1_PS		0x80	/* power supply 1 present (reversed) */
+#define	CLK_PPRES		0x40	/* power supply presence register */
+#define	 CLK_PPRES_CSHARE	0x80	/* current share backplane */
+#define	 CLK_PPRES_OK_MASK	0x7f	/* precharge and peripheral pwr mask */
+#define	 CLK_PPRES_OK_P_5V	0x40	/* ok: peripheral 5V */
+#define	 CLK_PPRES_OK_P_12V	0x20	/* ok: peripheral 12V */
+#define	 CLK_PPRES_OK_AUX_5V	0x10	/* ok: auxiliary 5V */
+#define	 CLK_PPRES_OK_PP_5V	0x08	/* ok: peripheral 5V precharge */
+#define	 CLK_PPRES_OK_PP_12V	0x04	/* ok: peripheral 12V precharge */
+#define	 CLK_PPRES_OK_SP_3V	0x02	/* ok: system 3.3V precharge */
+#define	 CLK_PPRES_OK_SP_5V	0x01	/* ok: system 5V precharge */
+#define	CLK_TEMP		0x50	/* temperature register */
+#define	CLK_IDIAG		0x60	/* interrupt diagnostic register */
+#define	CLK_PSTS2		0x70	/* power supply 2 status register */
+
+/* register bank 2 */
+#define CLKVER_SLOTS		0x00	/* clock version slots register */
+#define	 CLKVER_SLOTS_MASK	0x80	/* clock version slots mask */
+#define	 CLKVER_SLOTS_PLUS	0x00	/* plus system (reversed) */
+
+#endif /* !_SPARC64_FHC_CLKBRDREG_H_ */


Property changes on: trunk/sys/sparc64/fhc/clkbrdreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/fhc/fhc.c
===================================================================
--- trunk/sys/sparc64/fhc/fhc.c	                        (rev 0)
+++ trunk/sys/sparc64/fhc/fhc.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,536 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Jake Burkholder.
+ * Copyright (c) 2005 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/fhc/fhc.c 227848 2011-11-22 21:55:40Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/pcpu.h>
+
+#include <dev/led/led.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/bus_common.h>
+#include <machine/resource.h>
+
+#include <sys/rman.h>
+
+#include <sparc64/fhc/fhcreg.h>
+#include <sparc64/sbus/ofw_sbus.h>
+
+struct fhc_devinfo {
+	struct ofw_bus_devinfo	fdi_obdinfo;
+	struct resource_list	fdi_rl;
+};
+
+struct fhc_softc {
+	struct resource		*sc_memres[FHC_NREG];
+	int			sc_nrange;
+	struct sbus_ranges	*sc_ranges;
+	int			sc_ign;
+	struct cdev		*sc_led_dev;
+};
+
+static device_probe_t fhc_probe;
+static device_attach_t fhc_attach;
+static bus_print_child_t fhc_print_child;
+static bus_probe_nomatch_t fhc_probe_nomatch;
+static bus_setup_intr_t fhc_setup_intr;
+static bus_alloc_resource_t fhc_alloc_resource;
+static bus_adjust_resource_t fhc_adjust_resource;
+static bus_get_resource_list_t fhc_get_resource_list;
+static ofw_bus_get_devinfo_t fhc_get_devinfo;
+
+static void fhc_intr_enable(void *);
+static void fhc_intr_disable(void *);
+static void fhc_intr_assign(void *);
+static void fhc_intr_clear(void *);
+static void fhc_led_func(void *, int);
+static int fhc_print_res(struct fhc_devinfo *);
+
+static device_method_t fhc_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		fhc_probe),
+	DEVMETHOD(device_attach,	fhc_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	fhc_print_child),
+	DEVMETHOD(bus_probe_nomatch,	fhc_probe_nomatch),
+	DEVMETHOD(bus_alloc_resource,	fhc_alloc_resource),
+	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	fhc_adjust_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_rl_release_resource),
+	DEVMETHOD(bus_setup_intr,	fhc_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	DEVMETHOD(bus_get_resource_list, fhc_get_resource_list),
+	DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	fhc_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	DEVMETHOD_END
+};
+
+static driver_t fhc_driver = {
+	"fhc",
+	fhc_methods,
+	sizeof(struct fhc_softc),
+};
+
+static devclass_t fhc_devclass;
+
+EARLY_DRIVER_MODULE(fhc, central, fhc_driver, fhc_devclass, 0, 0,
+    BUS_PASS_BUS);
+MODULE_DEPEND(fhc, central, 1, 1, 1);
+EARLY_DRIVER_MODULE(fhc, nexus, fhc_driver, fhc_devclass, 0, 0,
+    BUS_PASS_BUS);
+MODULE_DEPEND(fhc, nexus, 1, 1, 1);
+MODULE_VERSION(fhc, 1);
+
+static const struct intr_controller fhc_ic = {
+	fhc_intr_enable,
+	fhc_intr_disable,
+	fhc_intr_assign,
+	fhc_intr_clear
+};
+
+struct fhc_icarg {
+	struct fhc_softc	*fica_sc;
+	struct resource		*fica_memres;
+};
+
+static int
+fhc_probe(device_t dev)
+{
+
+	if (strcmp(ofw_bus_get_name(dev), "fhc") == 0) {
+		device_set_desc(dev, "fhc");
+		return (0);
+	}
+	return (ENXIO);
+}
+
+static int
+fhc_attach(device_t dev)
+{
+	char ledname[sizeof("boardXX")];
+	struct fhc_devinfo *fdi;
+	struct fhc_icarg *fica;
+	struct fhc_softc *sc;
+	struct sbus_regs *reg;
+	phandle_t child;
+	phandle_t node;
+	device_t cdev;
+	uint32_t board;
+	uint32_t ctrl;
+	uint32_t *intr;
+	uint32_t iv;
+	char *name;
+	int central;
+	int error;
+	int i;
+	int j;
+
+	sc = device_get_softc(dev);
+	node = ofw_bus_get_node(dev);
+
+	central = 0;
+	if (strcmp(device_get_name(device_get_parent(dev)), "central") == 0)
+		central = 1;
+
+	for (i = 0; i < FHC_NREG; i++) {
+		j = i;
+		sc->sc_memres[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+		    &j, RF_ACTIVE);
+		if (sc->sc_memres[i] == NULL) {
+			device_printf(dev, "cannot allocate resource %d\n", i);
+			error = ENXIO;
+			goto fail_memres;
+		}
+	}
+
+	if (central != 0) {
+		board = bus_read_4(sc->sc_memres[FHC_INTERNAL], FHC_BSR);
+		board = ((board >> 16) & 0x1) | ((board >> 12) & 0xe);
+	} else {
+		if (OF_getprop(node, "board#", &board, sizeof(board)) == -1) {
+			device_printf(dev, "cannot get board number\n");
+			error = ENXIO;
+			goto fail_memres;
+		}
+	}
+
+	device_printf(dev, "board %d, ", board);
+	if (OF_getprop_alloc(node, "board-model", 1, (void **)&name) != -1) {
+		printf("model %s\n", name);
+		free(name, M_OFWPROP);
+	} else
+		printf("model unknown\n");
+
+	for (i = FHC_FANFAIL; i <= FHC_TOD; i++) {
+		bus_write_4(sc->sc_memres[i], FHC_ICLR, INTCLR_IDLE);
+		(void)bus_read_4(sc->sc_memres[i], FHC_ICLR);
+	}
+
+	sc->sc_ign = board << 1;
+	bus_write_4(sc->sc_memres[FHC_IGN], 0x0, sc->sc_ign);
+	sc->sc_ign = bus_read_4(sc->sc_memres[FHC_IGN], 0x0);
+
+	ctrl = bus_read_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL);
+	if (central == 0)
+		ctrl |= FHC_CTRL_IXIST;
+	ctrl &= ~(FHC_CTRL_AOFF | FHC_CTRL_BOFF | FHC_CTRL_SLINE);
+	bus_write_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL, ctrl);
+	(void)bus_read_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL);
+
+	sc->sc_nrange = OF_getprop_alloc(node, "ranges",
+	    sizeof(*sc->sc_ranges), (void **)&sc->sc_ranges);
+	if (sc->sc_nrange == -1) {
+		device_printf(dev, "cannot get ranges\n");
+		error = ENXIO;
+		goto fail_memres;
+	}
+
+	/*
+	 * Apparently only the interrupt controller of boards hanging off
+	 * of central(4) is indented to be used, otherwise we would have
+	 * conflicts registering the interrupt controllers for all FHC
+	 * boards as the board number and thus the IGN isn't unique.
+	 */
+	if (central == 1) {
+		/*
+		 * Hunt through all the interrupt mapping regs and register
+		 * our interrupt controller for the corresponding interrupt
+		 * vectors.  We do this early in order to be able to catch
+		 * stray interrupts.
+		 */
+		for (i = FHC_FANFAIL; i <= FHC_TOD; i++) {
+			fica = malloc(sizeof(*fica), M_DEVBUF, M_NOWAIT);
+			if (fica == NULL)
+				panic("%s: could not allocate interrupt "
+				    "controller argument", __func__);
+			fica->fica_sc = sc;
+			fica->fica_memres = sc->sc_memres[i];
+#ifdef FHC_DEBUG
+			device_printf(dev, "intr map %d: %#lx, clr: %#lx\n", i,
+			    (u_long)bus_read_4(fica->fica_memres, FHC_IMAP),
+			    (u_long)bus_read_4(fica->fica_memres, FHC_ICLR));
+#endif
+			/*
+			 * XXX we only pick the INO rather than the INR
+			 * from the IMR since the firmware may not provide
+			 * the IGN and the IGN is constant for all devices
+			 * on that FireHose controller.
+			 */
+			j = intr_controller_register(INTMAP_VEC(sc->sc_ign,
+			    INTINO(bus_read_4(fica->fica_memres, FHC_IMAP))),
+			    &fhc_ic, fica);
+			if (j != 0)
+				device_printf(dev, "could not register "
+				    "interrupt controller for map %d (%d)\n",
+				    i, j);
+		}
+	} else {
+		snprintf(ledname, sizeof(ledname), "board%d", board);
+		sc->sc_led_dev = led_create(fhc_led_func, sc, ledname);
+	}
+
+	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+		fdi = malloc(sizeof(*fdi), M_DEVBUF, M_WAITOK | M_ZERO);
+		if (ofw_bus_gen_setup_devinfo(&fdi->fdi_obdinfo, child) != 0) {
+			free(fdi, M_DEVBUF);
+			continue;
+		}
+		i = OF_getprop_alloc(child, "reg", sizeof(*reg),
+		    (void **)&reg);
+		if (i == -1) {
+			device_printf(dev, "<%s>: incomplete\n",
+			    fdi->fdi_obdinfo.obd_name);
+			ofw_bus_gen_destroy_devinfo(&fdi->fdi_obdinfo);
+			free(fdi, M_DEVBUF);
+			continue;
+		}
+		resource_list_init(&fdi->fdi_rl);
+		for (j = 0; j < i; j++)
+			resource_list_add(&fdi->fdi_rl, SYS_RES_MEMORY, j,
+			    reg[j].sbr_offset, reg[j].sbr_offset +
+			    reg[j].sbr_size, reg[j].sbr_size);
+		free(reg, M_OFWPROP);
+		if (central == 1) {
+			i = OF_getprop_alloc(child, "interrupts",
+			    sizeof(*intr), (void **)&intr);
+			if (i != -1) {
+				for (j = 0; j < i; j++) {
+					iv = INTMAP_VEC(sc->sc_ign, intr[j]);
+					resource_list_add(&fdi->fdi_rl,
+					    SYS_RES_IRQ, j, iv, iv, 1);
+				}
+				free(intr, M_OFWPROP);
+			}
+		}
+		cdev = device_add_child(dev, NULL, -1);
+		if (cdev == NULL) {
+			device_printf(dev, "<%s>: device_add_child failed\n",
+			    fdi->fdi_obdinfo.obd_name);
+			resource_list_free(&fdi->fdi_rl);
+			ofw_bus_gen_destroy_devinfo(&fdi->fdi_obdinfo);
+			free(fdi, M_DEVBUF);
+			continue;
+		}
+		device_set_ivars(cdev, fdi);
+	}
+
+	return (bus_generic_attach(dev));
+
+ fail_memres:
+	for (i = 0; i < FHC_NREG; i++)
+		if (sc->sc_memres[i] != NULL)
+			bus_release_resource(dev, SYS_RES_MEMORY,
+			    rman_get_rid(sc->sc_memres[i]), sc->sc_memres[i]);
+	return (error);
+}
+
+static int
+fhc_print_child(device_t dev, device_t child)
+{
+	int rv;
+
+	rv = bus_print_child_header(dev, child);
+	rv += fhc_print_res(device_get_ivars(child));
+	rv += bus_print_child_footer(dev, child);
+	return (rv);
+}
+
+static void
+fhc_probe_nomatch(device_t dev, device_t child)
+{
+	const char *type;
+
+	device_printf(dev, "<%s>", ofw_bus_get_name(child));
+	fhc_print_res(device_get_ivars(child));
+	type = ofw_bus_get_type(child);
+	printf(" type %s (no driver attached)\n",
+	    type != NULL ? type : "unknown");
+}
+
+static void
+fhc_intr_enable(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct fhc_icarg *fica = iv->iv_icarg;
+
+	bus_write_4(fica->fica_memres, FHC_IMAP,
+	    INTMAP_ENABLE(iv->iv_vec, iv->iv_mid));
+	(void)bus_read_4(fica->fica_memres, FHC_IMAP);
+}
+
+static void
+fhc_intr_disable(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct fhc_icarg *fica = iv->iv_icarg;
+
+	bus_write_4(fica->fica_memres, FHC_IMAP, iv->iv_vec);
+	(void)bus_read_4(fica->fica_memres, FHC_IMAP);
+}
+
+static void
+fhc_intr_assign(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct fhc_icarg *fica = iv->iv_icarg;
+
+	bus_write_4(fica->fica_memres, FHC_IMAP, INTMAP_TID(
+	    bus_read_4(fica->fica_memres, FHC_IMAP), iv->iv_mid));
+	(void)bus_read_4(fica->fica_memres, FHC_IMAP);
+}
+
+static void
+fhc_intr_clear(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct fhc_icarg *fica = iv->iv_icarg;
+
+	bus_write_4(fica->fica_memres, FHC_ICLR, INTCLR_IDLE);
+	(void)bus_read_4(fica->fica_memres, FHC_ICLR);
+}
+
+static int
+fhc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
+    driver_filter_t *filt, driver_intr_t *func, void *arg, void **cookiep)
+{
+	struct fhc_softc *sc;
+	u_long vec;
+
+	sc = device_get_softc(bus);
+	/*
+	 * Make sure the vector is fully specified and we registered
+	 * our interrupt controller for it.
+	 */
+	vec = rman_get_start(r);
+	if (INTIGN(vec) != sc->sc_ign || intr_vectors[vec].iv_ic != &fhc_ic) {
+		device_printf(bus, "invalid interrupt vector 0x%lx\n", vec);
+		return (EINVAL);
+	}
+	return (bus_generic_setup_intr(bus, child, r, flags, filt, func,
+	    arg, cookiep));
+}
+
+static struct resource *
+fhc_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct resource_list *rl;
+	struct resource_list_entry *rle;
+	struct fhc_softc *sc;
+	struct resource *res;
+	bus_addr_t coffset;
+	bus_addr_t cend;
+	bus_addr_t phys;
+	int isdefault;
+	int passthrough;
+	int i;
+
+	isdefault = (start == 0UL && end == ~0UL);
+	passthrough = (device_get_parent(child) != bus);
+	res = NULL;
+	rle = NULL;
+	rl = BUS_GET_RESOURCE_LIST(bus, child);
+	sc = device_get_softc(bus);
+	switch (type) {
+	case SYS_RES_IRQ:
+		return (resource_list_alloc(rl, bus, child, type, rid, start,
+		    end, count, flags));
+	case SYS_RES_MEMORY:
+		if (!passthrough) {
+			rle = resource_list_find(rl, type, *rid);
+			if (rle == NULL)
+				return (NULL);
+			if (rle->res != NULL)
+				panic("%s: resource entry is busy", __func__);
+			if (isdefault) {
+				start = rle->start;
+				count = ulmax(count, rle->count);
+				end = ulmax(rle->end, start + count - 1);
+			}
+		}
+		for (i = 0; i < sc->sc_nrange; i++) {
+			coffset = sc->sc_ranges[i].coffset;
+			cend = coffset + sc->sc_ranges[i].size - 1;
+			if (start >= coffset && end <= cend) {
+				start -= coffset;
+				end -= coffset;
+				phys = sc->sc_ranges[i].poffset |
+				    ((bus_addr_t)sc->sc_ranges[i].pspace << 32);
+				res = bus_generic_alloc_resource(bus, child,
+				    type, rid, phys + start, phys + end,
+				    count, flags);
+				if (!passthrough)
+					rle->res = res;
+				break;
+			}
+		}
+		break;
+	}
+	return (res);
+}
+
+static int
+fhc_adjust_resource(device_t bus __unused, device_t child __unused,
+    int type __unused, struct resource *r __unused, u_long start __unused,
+    u_long end __unused)
+{
+
+	return (ENXIO);
+}
+
+static struct resource_list *
+fhc_get_resource_list(device_t bus, device_t child)
+{
+	struct fhc_devinfo *fdi;
+
+	fdi = device_get_ivars(child);
+	return (&fdi->fdi_rl);
+}
+
+static const struct ofw_bus_devinfo *
+fhc_get_devinfo(device_t bus, device_t child)
+{
+	struct fhc_devinfo *fdi;
+
+	fdi = device_get_ivars(child);
+	return (&fdi->fdi_obdinfo);
+}
+
+static void
+fhc_led_func(void *arg, int onoff)
+{
+	struct fhc_softc *sc;
+	uint32_t ctrl;
+
+	sc = (struct fhc_softc *)arg;
+
+	ctrl = bus_read_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL);
+	if (onoff)
+		ctrl |= FHC_CTRL_RLED;
+	else
+		ctrl &= ~FHC_CTRL_RLED;
+	ctrl &= ~(FHC_CTRL_AOFF | FHC_CTRL_BOFF | FHC_CTRL_SLINE);
+	bus_write_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL, ctrl);
+	(void)bus_read_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL);
+}
+
+static int
+fhc_print_res(struct fhc_devinfo *fdi)
+{
+	int rv;
+
+	rv = 0;
+	rv += resource_list_print_type(&fdi->fdi_rl, "mem", SYS_RES_MEMORY,
+	    "%#lx");
+	rv += resource_list_print_type(&fdi->fdi_rl, "irq", SYS_RES_IRQ, "%ld");
+	return (rv);
+}


Property changes on: trunk/sys/sparc64/fhc/fhc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/fhc/fhcreg.h
===================================================================
--- trunk/sys/sparc64/fhc/fhcreg.h	                        (rev 0)
+++ trunk/sys/sparc64/fhc/fhcreg.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,96 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Jake Burkholder.
+ * 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.
+ */
+/*-
+ * Copyright (c) 2004 Jason L. Wright (jason at thought.net).
+ * 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 ``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.
+ *
+ *	from: OpenBSD: fhcreg.h,v 1.3 2004/09/28 16:26:03 jason Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/fhc/fhcreg.h 143825 2005-03-19 00:48:34Z marius $
+ */
+
+#ifndef _SPARC64_FHC_FHCREG_H_
+#define	_SPARC64_FHC_FHCREG_H_
+
+#define	FHC_NREG	(6)
+
+#define	FHC_INTERNAL	(0)
+#define	FHC_IGN		(1)
+#define	FHC_FANFAIL	(2)
+#define	FHC_SYSTEM	(3)
+#define	FHC_UART	(4)
+#define	FHC_TOD		(5)
+
+#define	FHC_IMAP	0x0
+#define	FHC_ICLR	0x10
+
+#define	FHC_ID		0x00000000	/* ID */
+#define	FHC_RCS		0x00000010	/* reset ctrl/status */
+#define	FHC_CTRL	0x00000020	/* control */
+#define	FHC_BSR		0x00000030	/* board status */
+#define	FHC_ECC		0x00000040	/* ECC control */
+#define	FHC_JCTRL	0x000000f0	/* JTAG control */
+
+#define	FHC_CTRL_ICS	0x00100000	/* ignore centerplane sigs */
+#define	FHC_CTRL_FRST	0x00080000	/* fatal error reset enable */
+#define	FHC_CTRL_LFAT	0x00040000	/* AC/DC local error */
+#define	FHC_CTRL_SLINE	0x00010000	/* firmware sync line */
+#define	FHC_CTRL_DCD	0x00008000	/* DC/DC converter disable */
+#define	FHC_CTRL_POFF	0x00004000	/* AC/DC ctlr PLL disable */
+#define	FHC_CTRL_FOFF	0x00002000	/* FHC ctlr PLL disable */
+#define	FHC_CTRL_AOFF	0x00001000	/* cpu a sram low pwr mode */
+#define	FHC_CTRL_BOFF	0x00000800	/* cpu b sram low pwr mode */
+#define	FHC_CTRL_PSOFF	0x00000400	/* disable fhc power supply */
+#define	FHC_CTRL_IXIST	0x00000200	/* fhc notifies clock-board */
+#define	FHC_CTRL_XMSTR	0x00000100	/* xir master enable */
+#define	FHC_CTRL_LLED	0x00000040	/* left led (reversed) */
+#define	FHC_CTRL_MLED	0x00000020	/* middle led */
+#define	FHC_CTRL_RLED	0x00000010	/* right led */
+#define	FHC_CTRL_BPINS	0x00000003	/* spare bidir pins */
+
+#endif /* !_SPARC64_FHC_FHCREG_H_ */


Property changes on: trunk/sys/sparc64/fhc/fhcreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/_align.h
===================================================================
--- trunk/sys/sparc64/include/_align.h	                        (rev 0)
+++ trunk/sys/sparc64/include/_align.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,45 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: @(#)param.h	5.8 (Berkeley) 6/28/91
+ * $FreeBSD: stable/10/sys/sparc64/include/_align.h 196994 2009-09-08 20:45:40Z phk $
+ */
+
+#ifndef _SPARC64_INCLUDE__ALIGN_H_
+#define	_SPARC64_INCLUDE__ALIGN_H_
+
+/*
+ * Round p (pointer or byte index) up to a correctly-aligned value
+ * for all data types (int, long, ...).   The result is unsigned int
+ * and must be cast to any desired pointer type.
+ */
+#define _ALIGNBYTES	0xf
+#define _ALIGN(p)	(((u_long)(p) + _ALIGNBYTES) & ~_ALIGNBYTES)
+
+#endif /* !_SPARC64_INCLUDE__ALIGN_H_ */


Property changes on: trunk/sys/sparc64/include/_align.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/_bus.h
===================================================================
--- trunk/sys/sparc64/include/_bus.h	                        (rev 0)
+++ trunk/sys/sparc64/include/_bus.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,40 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 M. Warner Losh.
+ * 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,
+ *    without modification, immediately at the beginning of the file.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/_bus.h 159583 2006-06-13 19:18:09Z marius $
+ */
+
+#ifndef SPARC64_INCLUDE__BUS_H
+#define SPARC64_INCLUDE__BUS_H
+
+typedef u_long bus_addr_t;
+typedef u_long bus_size_t;
+typedef u_long bus_space_handle_t;
+typedef struct bus_space_tag *bus_space_tag_t;
+
+#endif /* SPARC64_INCLUDE__BUS_H */


Property changes on: trunk/sys/sparc64/include/_bus.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/_inttypes.h
===================================================================
--- trunk/sys/sparc64/include/_inttypes.h	                        (rev 0)
+++ trunk/sys/sparc64/include/_inttypes.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,214 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Klaus Klein.
+ *
+ * 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 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.
+ *
+ *	From: $NetBSD: int_fmtio.h,v 1.4 2008/04/28 20:23:36 martin Exp $
+ * $FreeBSD: stable/10/sys/sparc64/include/_inttypes.h 219567 2011-03-12 14:33:32Z marius $
+ */
+
+#ifndef _MACHINE_INTTYPES_H_
+#define _MACHINE_INTTYPES_H_
+
+/*
+ * Macros for format specifiers.
+ */
+
+/* fprintf(3) macros for signed integers. */
+
+#define	PRId8		"d"	/* int8_t */
+#define	PRId16		"d"	/* int16_t */
+#define	PRId32		"d"	/* int32_t */
+#define	PRId64		"ld"	/* int64_t */
+#define	PRIdLEAST8	"d"	/* int_least8_t */
+#define	PRIdLEAST16	"d"	/* int_least16_t */
+#define	PRIdLEAST32	"d"	/* int_least32_t */
+#define	PRIdLEAST64	"ld"	/* int_least64_t */
+#define	PRIdFAST8	"d"	/* int_fast8_t */
+#define	PRIdFAST16	"d"	/* int_fast16_t */
+#define	PRIdFAST32	"d"	/* int_fast32_t */
+#define	PRIdFAST64	"ld"	/* int_fast64_t */
+#define	PRIdMAX		"jd"	/* intmax_t */
+#define	PRIdPTR		"ld"	/* intptr_t */
+
+#define	PRIi8		"i"	/* int8_t */
+#define	PRIi16		"i"	/* int16_t */
+#define	PRIi32		"i"	/* int32_t */
+#define	PRIi64		"li"	/* int64_t */
+#define	PRIiLEAST8	"i"	/* int_least8_t  */
+#define	PRIiLEAST16	"i"	/* int_least16_t */
+#define	PRIiLEAST32	"i"	/* int_least32_t */
+#define	PRIiLEAST64	"li"	/* int_least64_t */
+#define	PRIiFAST8	"i"	/* int_fast8_t */
+#define	PRIiFAST16	"i"	/* int_fast16_t */
+#define	PRIiFAST32	"i"	/* int_fast32_t */
+#define	PRIiFAST64	"li"	/* int_fast64_t */
+#define	PRIiMAX		"ji"	/* intmax_t */
+#define	PRIiPTR		"li"	/* intptr_t */
+
+/* fprintf(3) macros for unsigned integers. */
+
+#define	PRIo8		"o"	/* uint8_t */
+#define	PRIo16		"o"	/* uint16_t */
+#define	PRIo32		"o"	/* uint32_t */
+#define	PRIo64		"lo"	/* uint64_t */
+#define	PRIoLEAST8	"o"	/* uint_least8_t */
+#define	PRIoLEAST16	"o"	/* uint_least16_t */
+#define	PRIoLEAST32	"o"	/* uint_least32_t */
+#define	PRIoLEAST64	"lo"	/* uint_least64_t */
+#define	PRIoFAST8	"o"	/* uint_fast8_t */
+#define	PRIoFAST16	"o"	/* uint_fast16_t */
+#define	PRIoFAST32	"o"	/* uint_fast32_t */
+#define	PRIoFAST64	"lo"	/* uint_fast64_t */
+#define	PRIoMAX		"jo"	/* uintmax_t */
+#define	PRIoPTR		"lo"	/* uintptr_t */
+
+#define	PRIu8		"u"	/* uint8_t */
+#define	PRIu16		"u"	/* uint16_t */
+#define	PRIu32		"u"	/* uint32_t */
+#define	PRIu64		"lu"	/* uint64_t */
+#define	PRIuLEAST8	"u"	/* uint_least8_t */
+#define	PRIuLEAST16	"u"	/* uint_least16_t */
+#define	PRIuLEAST32	"u"	/* uint_least32_t */
+#define	PRIuLEAST64	"lu"	/* uint_least64_t */
+#define	PRIuFAST8	"u"	/* uint_fast8_t */
+#define	PRIuFAST16	"u"	/* uint_fast16_t */
+#define	PRIuFAST32	"u"	/* uint_fast32_t */
+#define	PRIuFAST64	"lu"	/* uint_fast64_t */
+#define	PRIuMAX		"ju"	/* uintmax_t */
+#define	PRIuPTR		"lu"	/* uintptr_t */
+
+#define	PRIx8		"x"	/* uint8_t */
+#define	PRIx16		"x"	/* uint16_t */
+#define	PRIx32		"x"	/* uint32_t */
+#define	PRIx64		"lx"	/* uint64_t */
+#define	PRIxLEAST8	"x"	/* uint_least8_t */
+#define	PRIxLEAST16	"x"	/* uint_least16_t */
+#define	PRIxLEAST32	"x"	/* uint_least32_t */
+#define	PRIxLEAST64	"lx"	/* uint_least64_t */
+#define	PRIxFAST8	"x"	/* uint_fast8_t */
+#define	PRIxFAST16	"x"	/* uint_fast16_t */
+#define	PRIxFAST32	"x"	/* uint_fast32_t */
+#define	PRIxFAST64	"lx"	/* uint_fast64_t */
+#define	PRIxMAX		"jx"	/* uintmax_t */
+#define	PRIxPTR		"lx"	/* uintptr_t */
+
+#define	PRIX8		"X"	/* uint8_t */
+#define	PRIX16		"X"	/* uint16_t */
+#define	PRIX32		"X"	/* uint32_t */
+#define	PRIX64		"lX"	/* uint64_t */
+#define	PRIXLEAST8	"X"	/* uint_least8_t */
+#define	PRIXLEAST16	"X"	/* uint_least16_t */
+#define	PRIXLEAST32	"X"	/* uint_least32_t */
+#define	PRIXLEAST64	"lX"	/* uint_least64_t */
+#define	PRIXFAST8	"X"	/* uint_fast8_t */
+#define	PRIXFAST16	"X"	/* uint_fast16_t */
+#define	PRIXFAST32	"X"	/* uint_fast32_t */
+#define	PRIXFAST64	"lX"	/* uint_fast64_t */
+#define	PRIXMAX		"jX"	/* uintmax_t */
+#define	PRIXPTR		"lX"	/* uintptr_t */
+
+/* fscanf(3) macros for signed integers. */
+
+#define	SCNd8		"hhd"	/* int8_t */
+#define	SCNd16		"hd"	/* int16_t */
+#define	SCNd32		"d"	/* int32_t */
+#define	SCNd64		"ld"	/* int64_t */
+#define	SCNdLEAST8	"hhd"	/* int_least8_t */
+#define	SCNdLEAST16	"hd"	/* int_least16_t */
+#define	SCNdLEAST32	"d"	/* int_least32_t */
+#define	SCNdLEAST64	"ld"	/* int_least64_t */
+#define	SCNdFAST8	"d"	/* int_fast8_t */
+#define	SCNdFAST16	"d"	/* int_fast16_t */
+#define	SCNdFAST32	"d"	/* int_fast32_t */
+#define	SCNdFAST64	"ld"	/* int_fast64_t */
+#define	SCNdMAX		"jd"	/* intmax_t */
+#define	SCNdPTR		"ld"	/* intptr_t */
+
+#define	SCNi8		"hhi"	/* int8_t */
+#define	SCNi16		"hi"	/* int16_t */
+#define	SCNi32		"i"	/* int32_t */
+#define	SCNi64		"li"	/* int64_t */
+#define	SCNiLEAST8	"hhi"	/* int_least8_t */
+#define	SCNiLEAST16	"hi"	/* int_least16_t */
+#define	SCNiLEAST32	"i"	/* int_least32_t */
+#define	SCNiLEAST64	"li"	/* int_least64_t */
+#define	SCNiFAST8	"i"	/* int_fast8_t */
+#define	SCNiFAST16	"i"	/* int_fast16_t */
+#define	SCNiFAST32	"i"	/* int_fast32_t */
+#define	SCNiFAST64	"li"	/* int_fast64_t */
+#define	SCNiMAX		"ji"	/* intmax_t */
+#define	SCNiPTR		"li"	/* intptr_t */
+
+/* fscanf(3) macros for unsigned integers. */
+
+#define	SCNo8		"hho"	/* uint8_t */
+#define	SCNo16		"ho"	/* uint16_t */
+#define	SCNo32		"o"	/* uint32_t */
+#define	SCNo64		"lo"	/* uint64_t */
+#define	SCNoLEAST8	"hho"	/* uint_least8_t */
+#define	SCNoLEAST16	"ho"	/* uint_least16_t */
+#define	SCNoLEAST32	"o"	/* uint_least32_t */
+#define	SCNoLEAST64	"lo"	/* uint_least64_t */
+#define	SCNoFAST8	"o"	/* uint_fast8_t */
+#define	SCNoFAST16	"o"	/* uint_fast16_t */
+#define	SCNoFAST32	"o"	/* uint_fast32_t */
+#define	SCNoFAST64	"lo"	/* uint_fast64_t */
+#define	SCNoMAX		"jo"	/* uintmax_t */
+#define	SCNoPTR		"lo"	/* uintptr_t */
+
+#define	SCNu8		"hhu"	/* uint8_t */
+#define	SCNu16		"hu"	/* uint16_t */
+#define	SCNu32		"u"	/* uint32_t */
+#define	SCNu64		"lu"	/* uint64_t */
+#define	SCNuLEAST8	"hhu"	/* uint_least8_t */
+#define	SCNuLEAST16	"hu"	/* uint_least16_t */
+#define	SCNuLEAST32	"u"	/* uint_least32_t */
+#define	SCNuLEAST64	"lu"	/* uint_least64_t */
+#define	SCNuFAST8	"u"	/* uint_fast8_t */
+#define	SCNuFAST16	"u"	/* uint_fast16_t */
+#define	SCNuFAST32	"u"	/* uint_fast32_t */
+#define	SCNuFAST64	"lu"	/* uint_fast64_t */
+#define	SCNuMAX		"ju"	/* uintmax_t */
+#define	SCNuPTR		"lu"	/* uintptr_t */
+
+#define	SCNx8		"hhx"	/* uint8_t */
+#define	SCNx16		"hx"	/* uint16_t */
+#define	SCNx32		"x"	/* uint32_t */
+#define	SCNx64		"lx"	/* uint64_t */
+#define	SCNxLEAST8	"hhx"	/* uint_least8_t */
+#define	SCNxLEAST16	"hx"	/* uint_least16_t */
+#define	SCNxLEAST32	"x"	/* uint_least32_t */
+#define	SCNxLEAST64	"lx"	/* uint_least64_t */
+#define	SCNxFAST8	"x"	/* uint_fast8_t */
+#define	SCNxFAST16	"x"	/* uint_fast16_t */
+#define	SCNxFAST32	"x"	/* uint_fast32_t */
+#define	SCNxFAST64	"lx"	/* uint_fast64_t */
+#define	SCNxMAX		"jx"	/* uintmax_t */
+#define	SCNxPTR		"lx"	/* uintptr_t */
+
+#endif /* !_MACHINE_INTTYPES_H_ */


Property changes on: trunk/sys/sparc64/include/_inttypes.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/_limits.h
===================================================================
--- trunk/sys/sparc64/include/_limits.h	                        (rev 0)
+++ trunk/sys/sparc64/include/_limits.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,86 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1988, 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.
+ *
+ * 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.
+ *
+ *	@(#)limits.h	8.3 (Berkeley) 1/4/94
+ * $FreeBSD: stable/10/sys/sparc64/include/_limits.h 217145 2011-01-08 11:13:34Z tijl $
+ */
+
+#ifndef	_MACHINE__LIMITS_H_
+#define	_MACHINE__LIMITS_H_
+
+/*
+ * According to ANSI (section 2.2.4.2), the values below must be usable by
+ * #if preprocessing directives.  Additionally, the expression must have the
+ * same type as would an expression that is an object of the corresponding
+ * type converted according to the integral promotions.  The subtraction for
+ * INT_MIN, etc., is so the value is not unsigned; e.g., 0x80000000 is an
+ * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2).
+ */
+
+#define	__CHAR_BIT	8		/* number of bits in a char */
+
+#define	__SCHAR_MAX	0x7f		/* max value for a signed char */
+#define	__SCHAR_MIN	(-0x7f-1)	/* min value for a signed char */
+
+#define	__UCHAR_MAX	0xff		/* max value for an unsigned char */
+
+#define	__USHRT_MAX	0xffff		/* max value for an unsigned short */
+#define	__SHRT_MAX	0x7fff		/* max value for a short */
+#define	__SHRT_MIN	(-0x7fff-1)	/* min value for a short */
+
+#define	__UINT_MAX	0xffffffff	/* max value for an unsigned int */
+#define	__INT_MAX	0x7fffffff	/* max value for an int */
+#define	__INT_MIN	(-0x7fffffff-1)	/* min value for an int */
+
+#define	__ULONG_MAX	0xffffffffffffffff	/* max for an unsigned long */
+#define	__LONG_MAX	0x7fffffffffffffff	/* max for a long */
+#define	__LONG_MIN	(-0x7fffffffffffffff-1) /* min for a long */
+
+/* Long longs have the same size but not the same type as longs. */
+					/* max for an unsigned long long */
+#define	__ULLONG_MAX	0xffffffffffffffffULL
+#define	__LLONG_MAX	0x7fffffffffffffffLL	/* max for a long long */
+#define	__LLONG_MIN	(-0x7fffffffffffffffLL-1) /* min for a long long */
+
+#define	__SSIZE_MAX	__LONG_MAX	/* max value for a ssize_t */
+
+#define	__SIZE_T_MAX	__ULONG_MAX	/* max value for a size_t */
+
+#define	__OFF_MAX	__LONG_MAX	/* max value for an off_t */
+#define	__OFF_MIN	__LONG_MIN	/* min value for an off_t */
+
+/* Quads and longs are the same size.  Ensure they stay in sync. */
+#define	__UQUAD_MAX	(__ULONG_MAX)	/* max value for a uquad_t */
+#define	__QUAD_MAX	(__LONG_MAX)	/* max value for a quad_t */
+#define	__QUAD_MIN	(__LONG_MIN)	/* min value for a quad_t */
+
+#define	__LONG_BIT	64
+#define	__WORD_BIT	32
+
+/* Minimum signal stack size. */
+#define	__MINSIGSTKSZ	(1024 * 4)
+
+#endif /* !_MACHINE__LIMITS_H_ */


Property changes on: trunk/sys/sparc64/include/_limits.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/_stdint.h
===================================================================
--- trunk/sys/sparc64/include/_stdint.h	                        (rev 0)
+++ trunk/sys/sparc64/include/_stdint.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,159 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001, 2002 Mike Barcroft <mike at FreeBSD.org>
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Klaus Klein.
+ *
+ * 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 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/_stdint.h 237517 2012-06-24 04:15:58Z andrew $
+ */
+
+#ifndef	_MACHINE__STDINT_H_
+#define	_MACHINE__STDINT_H_
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
+
+#define	INT8_C(c)		(c)
+#define	INT16_C(c)		(c)
+#define	INT32_C(c)		(c)
+#define	INT64_C(c)		(c ## L)
+
+#define	UINT8_C(c)		(c)
+#define	UINT16_C(c)		(c)
+#define	UINT32_C(c)		(c ## U)
+#define	UINT64_C(c)		(c ## UL)
+
+#define	INTMAX_C(c)		INT64_C(c)
+#define	UINTMAX_C(c)		UINT64_C(c)
+
+#endif /* !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) */
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.1 Limits of exact-width integer types
+ */
+/* Minimum values of exact-width signed integer types. */
+#define	INT8_MIN	(-0x7f-1)
+#define	INT16_MIN	(-0x7fff-1)
+#define	INT32_MIN	(-0x7fffffff-1)
+#define	INT64_MIN	(-0x7fffffffffffffffL-1)
+
+/* Maximum values of exact-width signed integer types. */
+#define	INT8_MAX	0x7f
+#define	INT16_MAX	0x7fff
+#define	INT32_MAX	0x7fffffff
+#define	INT64_MAX	0x7fffffffffffffffL
+
+/* Maximum values of exact-width unsigned integer types. */
+#define	UINT8_MAX	0xff
+#define	UINT16_MAX	0xffff
+#define	UINT32_MAX	0xffffffffU
+#define	UINT64_MAX	0xffffffffffffffffUL
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.2  Limits of minimum-width integer types
+ */
+/* Minimum values of minimum-width signed integer types. */
+#define	INT_LEAST8_MIN	INT8_MIN
+#define	INT_LEAST16_MIN	INT16_MIN
+#define	INT_LEAST32_MIN	INT32_MIN
+#define	INT_LEAST64_MIN	INT64_MIN
+
+/* Maximum values of minimum-width signed integer types. */
+#define	INT_LEAST8_MAX	INT8_MAX
+#define	INT_LEAST16_MAX	INT16_MAX
+#define	INT_LEAST32_MAX	INT32_MAX
+#define	INT_LEAST64_MAX	INT64_MAX
+
+/* Maximum values of minimum-width unsigned integer types. */
+#define	UINT_LEAST8_MAX	 UINT8_MAX
+#define	UINT_LEAST16_MAX UINT16_MAX
+#define	UINT_LEAST32_MAX UINT32_MAX
+#define	UINT_LEAST64_MAX UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.3  Limits of fastest minimum-width integer types
+ */
+/* Minimum values of fastest minimum-width signed integer types. */
+#define	INT_FAST8_MIN	INT32_MIN
+#define	INT_FAST16_MIN	INT32_MIN
+#define	INT_FAST32_MIN	INT32_MIN
+#define	INT_FAST64_MIN	INT64_MIN
+
+/* Maximum values of fastest minimum-width signed integer types. */
+#define	INT_FAST8_MAX	INT32_MAX
+#define	INT_FAST16_MAX	INT32_MAX
+#define	INT_FAST32_MAX	INT32_MAX
+#define	INT_FAST64_MAX	INT64_MAX
+
+/* Maximum values of fastest minimum-width unsigned integer types. */
+#define	UINT_FAST8_MAX	UINT32_MAX
+#define	UINT_FAST16_MAX	UINT32_MAX
+#define	UINT_FAST32_MAX	UINT32_MAX
+#define	UINT_FAST64_MAX	UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.4  Limits of integer types capable of holding object pointers
+ */
+#define	INTPTR_MIN	INT64_MIN
+#define	INTPTR_MAX	INT64_MAX
+#define	UINTPTR_MAX	UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.5  Limits of greatest-width integer types
+ */
+#define	INTMAX_MIN	INT64_MIN
+#define	INTMAX_MAX	INT64_MAX
+#define	UINTMAX_MAX	UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.3  Limits of other integer types
+ */
+/* Limits of ptrdiff_t. */
+#define	PTRDIFF_MIN	INT64_MIN	
+#define	PTRDIFF_MAX	INT64_MAX
+
+/* Limits of sig_atomic_t. */
+#define	SIG_ATOMIC_MIN	INT32_MIN
+#define	SIG_ATOMIC_MAX	INT32_MAX
+
+/* Limit of size_t. */
+#define	SIZE_MAX	UINT64_MAX
+
+/* Limits of wint_t. */
+#define	WINT_MIN	INT32_MIN
+#define	WINT_MAX	INT32_MAX
+
+#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */
+
+#endif /* !_MACHINE__STDINT_H_ */


Property changes on: trunk/sys/sparc64/include/_stdint.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/_types.h
===================================================================
--- trunk/sys/sparc64/include/_types.h	                        (rev 0)
+++ trunk/sys/sparc64/include/_types.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,115 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike at FreeBSD.org>
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 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: @(#)ansi.h	8.2 (Berkeley) 1/4/94
+ *	From: @(#)types.h	8.3 (Berkeley) 1/5/94
+ * $FreeBSD: stable/10/sys/sparc64/include/_types.h 264496 2014-04-15 09:41:52Z tijl $
+ */
+
+#ifndef _MACHINE__TYPES_H_
+#define	_MACHINE__TYPES_H_
+
+#ifndef _SYS_CDEFS_H_
+#error this file needs sys/cdefs.h as a prerequisite
+#endif
+
+/*
+ * Basic types upon which most other types are built.
+ */
+typedef	signed char		__int8_t;
+typedef	unsigned char		__uint8_t;
+typedef	short			__int16_t;
+typedef	unsigned short		__uint16_t;
+typedef	int			__int32_t;
+typedef	unsigned int		__uint32_t;
+typedef	long			__int64_t;
+typedef	unsigned long		__uint64_t;
+
+/*
+ * Standard type definitions.
+ */
+typedef	__int32_t	__clock_t;		/* clock()... */
+typedef	__int64_t	__critical_t;
+typedef	double		__double_t;
+typedef	float		__float_t;
+typedef	__int64_t	__intfptr_t;
+typedef	__int64_t	__intmax_t;
+typedef	__int64_t	__intptr_t;
+typedef	__int32_t	__int_fast8_t;
+typedef	__int32_t	__int_fast16_t;
+typedef	__int32_t	__int_fast32_t;
+typedef	__int64_t	__int_fast64_t;
+typedef	__int8_t	__int_least8_t;
+typedef	__int16_t	__int_least16_t;
+typedef	__int32_t	__int_least32_t;
+typedef	__int64_t	__int_least64_t;
+typedef	__int64_t	__ptrdiff_t;		/* ptr1 - ptr2 */
+typedef	__int64_t	__register_t;
+typedef	__int64_t	__segsz_t;		/* segment size (in pages) */
+typedef	__uint64_t	__size_t;		/* sizeof() */
+typedef	__int64_t	__ssize_t;		/* byte count or error */
+typedef	__int64_t	__time_t;		/* time()... */
+typedef	__uint64_t	__uintfptr_t;
+typedef	__uint64_t	__uintmax_t;
+typedef	__uint64_t	__uintptr_t;
+typedef	__uint32_t	__uint_fast8_t;
+typedef	__uint32_t	__uint_fast16_t;
+typedef	__uint32_t	__uint_fast32_t;
+typedef	__uint64_t	__uint_fast64_t;
+typedef	__uint8_t	__uint_least8_t;
+typedef	__uint16_t	__uint_least16_t;
+typedef	__uint32_t	__uint_least32_t;
+typedef	__uint64_t	__uint_least64_t;
+typedef	__uint64_t	__u_register_t;
+typedef	__uint64_t	__vm_offset_t;
+typedef	__int64_t	__vm_ooffset_t;
+typedef	__uint64_t	__vm_paddr_t;
+typedef	__uint64_t	__vm_pindex_t;
+typedef	__uint64_t	__vm_size_t;
+typedef	int		___wchar_t;
+
+#define	__WCHAR_MIN	__INT_MIN	/* min value for a wchar_t */
+#define	__WCHAR_MAX	__INT_MAX	/* max value for a wchar_t */
+
+/*
+ * Unusual type definitions.
+ */
+#ifdef __GNUCLIKE_BUILTIN_VARARGS
+typedef __builtin_va_list	__va_list;	/* internally known to gcc */
+#else
+typedef	char *			__va_list;
+#endif /* __GNUCLIKE_BUILTIN_VARARGS */
+#if defined(__GNUCLIKE_BUILTIN_VAALIST) && !defined(__GNUC_VA_LIST) \
+    && !defined(__NO_GNUC_VA_LIST)
+#define __GNUC_VA_LIST
+typedef __va_list		__gnuc_va_list;	/* compatibility w/GNU headers*/
+#endif
+
+#endif /* !_MACHINE__TYPES_H_ */


Property changes on: trunk/sys/sparc64/include/_types.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/asi.h
===================================================================
--- trunk/sys/sparc64/include/asi.h	                        (rev 0)
+++ trunk/sys/sparc64/include/asi.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,261 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1997 Berkeley Software Design, Inc. 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. Berkeley Software Design Inc's name may not be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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: BSDI: asi.h,v 1.3 1997/08/08 14:31:42 torek
+ * $FreeBSD: stable/10/sys/sparc64/include/asi.h 207537 2010-05-02 19:38:17Z marius $
+ */
+
+#ifndef	_MACHINE_ASI_H_
+#define	_MACHINE_ASI_H_
+
+/*
+ * Standard v9 ASIs
+ */
+#define	ASI_N					0x4
+#define	ASI_NL					0xc
+#define	ASI_AIUP				0x10
+#define	ASI_AIUS				0x11
+#define	ASI_AIUPL				0x18
+#define	ASI_AIUSL				0x19
+#define	ASI_P					0x80
+#define	ASI_S					0x81
+#define	ASI_PNF					0x82
+#define	ASI_SNF					0x83
+#define	ASI_PL					0x88
+#define	ASI_SL					0x89
+#define	ASI_PNFL				0x8a
+#define	ASI_SNFL				0x8b
+
+/*
+ * UltraSPARC extensions - ASIs limited to a certain family are annotated.
+ */
+#define	ASI_PHYS_USE_EC				0x14
+#define	ASI_PHYS_BYPASS_EC_WITH_EBIT		0x15
+#define	ASI_PHYS_USE_EC_L			0x1c
+#define	ASI_PHYS_BYPASS_EC_WITH_EBIT_L		0x1d
+
+#define	ASI_NUCLEUS_QUAD_LDD			0x24
+#define	ASI_NUCLEUS_QUAD_LDD_L			0x2c
+
+#define	ASI_PCACHE_STATUS_DATA			0x30	/* US-III Cu */
+#define	ASI_PCACHE_DATA				0x31	/* US-III Cu */
+#define	ASI_PCACHE_TAG				0x32	/* US-III Cu */
+#define	ASI_PCACHE_SNOOP_TAG			0x33	/* US-III Cu */
+
+#define	ASI_ATOMIC_QUAD_LDD_PHYS		0x34	/* US-III Cu */
+
+#define	ASI_WCACHE_VALID_BITS			0x38	/* US-III Cu */
+#define	ASI_WCACHE_DATA				0x39	/* US-III Cu */
+#define	ASI_WCACHE_TAG				0x3a	/* US-III Cu */
+#define	ASI_WCACHE_SNOOP_TAG			0x3b	/* US-III Cu */
+
+#define	ASI_ATOMIC_QUAD_LDD_PHYS_L		0x3c	/* US-III Cu */
+
+#define	ASI_SRAM_FAST_INIT			0x40	/* US-III Cu */
+
+#define	ASI_DCACHE_INVALIDATE			0x42	/* US-III Cu */
+#define	ASI_DCACHE_UTAG				0x43	/* US-III Cu */
+#define	ASI_DCACHE_SNOOP_TAG			0x44	/* US-III Cu */
+
+/* Named ASI_DCUCR on US-III, but is mostly identical except for added bits. */
+#define	ASI_LSU_CTL_REG				0x45	/* US only */
+
+#define	ASI_MCNTL				0x45	/* SPARC64 only */
+#define		AA_MCNTL			0x08
+
+#define	ASI_DCACHE_DATA				0x46
+#define	ASI_DCACHE_TAG				0x47
+
+#define	ASI_INTR_DISPATCH_STATUS		0x48
+#define	ASI_INTR_RECEIVE			0x49
+#define	ASI_UPA_CONFIG_REG			0x4a	/* US-I, II */
+
+#define	ASI_FIREPLANE_CONFIG_REG		0x4a	/* US-III{,+}, IV{,+} */
+#define		AA_FIREPLANE_CONFIG		0x0	/* US-III{,+}, IV{,+} */
+#define		AA_FIREPLANE_ADDRESS		0x8	/* US-III{,+}, IV{,+} */
+#define		AA_FIREPLANE_CONFIG_2		0x10	/* US-IV{,+} */
+
+#define	ASI_JBUS_CONFIG_REG			0x4a	/* US-IIIi{,+} */
+
+#define	ASI_ESTATE_ERROR_EN_REG			0x4b
+#define		AA_ESTATE_CEEN			0x1
+#define		AA_ESTATE_NCEEN			0x2
+#define		AA_ESTATE_ISAPEN		0x4
+
+#define	ASI_AFSR				0x4c
+#define	ASI_AFAR				0x4d
+
+#define	ASI_ECACHE_TAG_DATA			0x4e
+
+#define	ASI_IMMU_TAG_TARGET_REG			0x50
+#define	ASI_IMMU				0x50
+#define		AA_IMMU_TTR			0x0
+#define		AA_IMMU_SFSR			0x18
+#define		AA_IMMU_TSB			0x28
+#define		AA_IMMU_TAR			0x30
+#define		AA_IMMU_TSB_PEXT_REG		0x48	/* US-III family */
+#define		AA_IMMU_TSB_SEXT_REG		0x50	/* US-III family */
+#define		AA_IMMU_TSB_NEXT_REG		0x58	/* US-III family */
+
+#define	ASI_IMMU_TSB_8KB_PTR_REG		0x51
+#define	ASI_IMMU_TSB_64KB_PTR_REG		0x52
+
+#define	ASI_SERIAL_ID				0x53	/* US-III family */
+
+#define	ASI_ITLB_DATA_IN_REG			0x54
+/* US-III Cu: also ASI_ITLB_CAM_ADDRESS_REG */
+#define	ASI_ITLB_DATA_ACCESS_REG		0x55
+#define	ASI_ITLB_TAG_READ_REG			0x56
+#define	ASI_IMMU_DEMAP				0x57
+
+#define	ASI_DMMU_TAG_TARGET_REG			0x58
+#define	ASI_DMMU				0x58
+#define		AA_DMMU_TTR			0x0
+#define		AA_DMMU_PCXR			0x8
+#define		AA_DMMU_SCXR			0x10
+#define		AA_DMMU_SFSR			0x18
+#define		AA_DMMU_SFAR			0x20
+#define		AA_DMMU_TSB			0x28
+#define		AA_DMMU_TAR			0x30
+#define		AA_DMMU_VWPR			0x38
+#define		AA_DMMU_PWPR			0x40
+#define		AA_DMMU_TSB_PEXT_REG		0x48
+#define		AA_DMMU_TSB_SEXT_REG		0x50
+#define		AA_DMMU_TSB_NEXT_REG		0x58
+#define		AA_DMMU_TAG_ACCESS_EXT		0x60	/* US-III family */
+
+#define	ASI_DMMU_TSB_8KB_PTR_REG		0x59
+#define	ASI_DMMU_TSB_64KB_PTR_REG		0x5a
+#define	ASI_DMMU_TSB_DIRECT_PTR_REG		0x5b
+#define	ASI_DTLB_DATA_IN_REG			0x5c
+/* US-III Cu: also ASI_DTLB_CAM_ADDRESS_REG */
+#define	ASI_DTLB_DATA_ACCESS_REG		0x5d
+#define	ASI_DTLB_TAG_READ_REG			0x5e
+#define	ASI_DMMU_DEMAP				0x5f
+
+#define	ASI_IIU_INST_TRAP			0x60	/* US-III family */
+
+#define	ASI_INTR_ID				0x63	/* US-IV{,+} */
+#define		AA_INTR_ID			0x0	/* US-IV{,+} */
+#define		AA_CORE_ID			0x10	/* US-IV{,+} */
+#define		AA_CESR_ID			0x40	/* US-IV{,+} */
+
+#define	ASI_ICACHE_INSTR			0x66
+#define	ASI_ICACHE_TAG				0x67
+#define	ASI_ICACHE_SNOOP_TAG			0x68	/* US-III family */
+#define	ASI_ICACHE_PRE_DECODE			0x6e	/* US-I, II */
+#define	ASI_ICACHE_PRE_NEXT_FIELD		0x6f	/* US-I, II */
+
+#define	ASI_FLUSH_L1I				0x67	/* SPARC64 only */
+
+#define	ASI_BLK_AUIP				0x70
+#define	ASI_BLK_AIUS				0x71
+
+#define	ASI_MCU_CONFIG_REG			0x72	/* US-III Cu */
+#define		AA_MCU_TIMING1_REG		0x0	/* US-III Cu */
+#define		AA_MCU_TIMING2_REG		0x8	/* US-III Cu */
+#define		AA_MCU_TIMING3_REG		0x10	/* US-III Cu */
+#define		AA_MCU_TIMING4_REG		0x18	/* US-III Cu */
+#define		AA_MCU_DEC1_REG			0x20	/* US-III Cu */
+#define		AA_MCU_DEC2_REG			0x28	/* US-III Cu */
+#define		AA_MCU_DEC3_REG			0x30	/* US-III Cu */
+#define		AA_MCU_DEC4_REG			0x38	/* US-III Cu */
+#define		AA_MCU_ADDR_CNTL_REG		0x40	/* US-III Cu */
+
+#define	ASI_ECACHE_DATA				0x74	/* US-III Cu */
+#define	ASI_ECACHE_CONTROL			0x75	/* US-III Cu */
+#define	ASI_ECACHE_W				0x76
+
+/*
+ * With the advent of the US-III, the numbering has changed, as additional
+ * registers were inserted in between.  We retain the original ordering for
+ * now, and append an A to the inserted registers.
+ * Exceptions are AA_SDB_INTR_D6 and AA_SDB_INTR_D7, which were appended
+ * at the end.
+ */
+#define	ASI_SDB_ERROR_W				0x77
+#define	ASI_SDB_CONTROL_W			0x77
+#define	ASI_SDB_INTR_W				0x77
+#define		AA_SDB_ERR_HIGH			0x0
+#define		AA_SDB_ERR_LOW			0x18
+#define		AA_SDB_CNTL_HIGH		0x20
+#define		AA_SDB_CNTL_LOW			0x38
+#define		AA_SDB_INTR_D0			0x40
+#define		AA_SDB_INTR_D0A			0x48	/* US-III family */
+#define		AA_SDB_INTR_D1			0x50
+#define		AA_SDB_INTR_D1A			0x5A	/* US-III family */
+#define		AA_SDB_INTR_D2			0x60
+#define		AA_SDB_INTR_D2A			0x68	/* US-III family */
+#define		AA_INTR_SEND			0x70
+#define		AA_SDB_INTR_D6			0x80	/* US-III family */
+#define		AA_SDB_INTR_D7			0x88	/* US-III family */
+
+#define	ASI_BLK_AIUPL				0x78
+#define	ASI_BLK_AIUSL				0x79
+
+#define	ASI_ECACHE_R				0x7e
+
+/*
+ * These have the same registers as their corresponding write versions
+ * except for AA_INTR_SEND.
+ */
+#define	ASI_SDB_ERROR_R				0x7f
+#define	ASI_SDB_CONTROL_R			0x7f
+#define	ASI_SDB_INTR_R				0x7f
+
+#define	ASI_PST8_P				0xc0
+#define	ASI_PST8_S				0xc1
+#define	ASI_PST16_P				0xc2
+#define	ASI_PST16_S				0xc3
+#define	ASI_PST32_P				0xc4
+#define	ASI_PST32_S				0xc5
+
+#define	ASI_PST8_PL				0xc8
+#define	ASI_PST8_SL				0xc9
+#define	ASI_PST16_PL				0xca
+#define	ASI_PST16_SL				0xcb
+#define	ASI_PST32_PL				0xcc
+#define	ASI_PST32_SL				0xcd
+
+#define	ASI_FL8_P				0xd0
+#define	ASI_FL8_S				0xd1
+#define	ASI_FL16_P				0xd2
+#define	ASI_FL16_S				0xd3
+#define	ASI_FL8_PL				0xd8
+#define	ASI_FL8_SL				0xd9
+#define	ASI_FL16_PL				0xda
+#define	ASI_FL16_SL				0xdb
+
+#define	ASI_BLK_COMMIT_P			0xe0
+#define	ASI_BLK_COMMIT_S			0xe1
+#define	ASI_BLK_P				0xf0
+#define	ASI_BLK_S				0xf1
+#define	ASI_BLK_PL				0xf8
+#define	ASI_BLK_SL				0xf9
+
+#endif /* !_MACHINE_ASI_H_ */


Property changes on: trunk/sys/sparc64/include/asi.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/asm.h
===================================================================
--- trunk/sys/sparc64/include/asm.h	                        (rev 0)
+++ trunk/sys/sparc64/include/asm.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,127 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 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: @(#)DEFS.h	5.1 (Berkeley) 4/23/90
+ *	from: FreeBSD: src/sys/i386/include/asm.h,v 1.7 2000/01/25
+ * $FreeBSD: stable/10/sys/sparc64/include/asm.h 279258 2015-02-24 22:28:44Z marius $
+ */
+
+#ifndef _MACHINE_ASM_H_
+#define	_MACHINE_ASM_H_
+
+#define	__ASM__
+
+#include <sys/cdefs.h>
+
+#ifdef PIC
+#define	PIC_PROLOGUE(r1, r2) \
+	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), r1 ; \
+	rd	%pc, r2 ; \
+	or	r1, %lo(_GLOBAL_OFFSET_TABLE_+4), r1 ; \
+	add	r2, r1, r2
+#define	SET(name, r1, r2) \
+	set	name, r2 ; \
+	ldx	[r1 + r2], r2
+#else
+#define	PIC_PROLOGUE(r1, r2)
+#define	SET(name, r1, r2) \
+	set	name, r2
+#endif
+
+/*
+ * CNAME and HIDENAME manage the relationship between symbol names in C
+ * and the equivalent assembly language names.  CNAME is given a name as
+ * it would be used in a C program.  It expands to the equivalent assembly
+ * language name.  HIDENAME is given an assembly-language name, and expands
+ * to a possibly-modified form that will be invisible to C programs.
+ */
+#define CNAME(csym)		csym
+#define HIDENAME(asmsym)	__CONCAT(.,asmsym)
+
+#define	CCFSZ	192
+#define	SPOFF	2047
+
+#define	_ALIGN_TEXT	.align 32
+
+#define _START_ENTRY \
+	.text ; \
+	_ALIGN_TEXT
+
+/*
+ * Define function entry and alternate entry points.
+ *
+ * The compiler produces #function for the .type pseudo-op, but the '#'
+ * character has special meaning in cpp macros, so we use @function like
+ * other architectures.  The assembler seems to accept both.
+ * The assembler also accepts a .proc pseudo-op, which is used by the
+ * peep hole optimizer, whose argument is the type code of the return
+ * value.  Since this is difficult to predict and its expected that
+ * assembler code is already optimized, we leave it out.
+ */
+
+#define	_ALTENTRY(x) \
+	.globl	CNAME(x) ; \
+	.type	CNAME(x), at function ; \
+CNAME(x):
+
+#define	_ENTRY(x) \
+	_START_ENTRY ; \
+	.globl	CNAME(x) ; \
+	.type	CNAME(x), at function ; \
+CNAME(x):
+
+#define	ALTENTRY(x)	_ALTENTRY(x)
+#define	ENTRY(x)	_ENTRY(x)
+#define	END(x)		.size x, . - x
+
+/*
+ * WEAK_REFERENCE(): create a weak reference alias from sym.
+ * The macro is not a general asm macro that takes arbitrary names,
+ * but one that takes only C names.  It does the non-null name
+ * translation inside the macro.
+ */
+#define	WEAK_REFERENCE(sym, alias) \
+	.weak	CNAME(alias); \
+	.equ	CNAME(alias),CNAME(sym)
+
+/*
+ * Kernel RCS ID tag and copyright macros
+ */
+
+#undef __FBSDID
+#if !defined(lint) && !defined(STRIP_FBSDID)
+#define __FBSDID(s)	.ident s
+#else
+#define __FBSDID(s)	/* nothing */
+#endif /* not lint and not STRIP_FBSDID */
+
+#endif /* !_MACHINE_ASM_H_ */


Property changes on: trunk/sys/sparc64/include/asm.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/asmacros.h
===================================================================
--- trunk/sys/sparc64/include/asmacros.h	                        (rev 0)
+++ trunk/sys/sparc64/include/asmacros.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,225 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * Copyright (c) 2011 Marius Strobl <marius at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/asmacros.h 226054 2011-10-06 11:01:31Z marius $
+ */
+
+#ifndef	_MACHINE_ASMACROS_H_
+#define	_MACHINE_ASMACROS_H_
+
+#ifdef _KERNEL
+
+/*
+ * Normal and alternate %g6 point to the pcb of the current process.  Normal,
+ * alternate and interrupt %g7 point to per-cpu data.
+ */
+#define	PCB_REG		%g6
+#define	PCPU_REG	%g7
+
+/*
+ * Alternate %g5 points to a per-cpu panic stack, which is used as a last
+ * resort, and for temporarily saving alternate globals.
+ */
+#define	ASP_REG		%g5
+
+#ifdef LOCORE
+
+/*
+ * Atomically decrement an integer in memory.
+ */
+#define	ATOMIC_DEC_INT(r1, r2, r3)					\
+	lduw	[r1], r2 ;						\
+9:	sub	r2, 1, r3 ;						\
+	casa	[r1] ASI_N, r2, r3 ;					\
+	cmp	r2, r3 ;						\
+	bne,pn	%icc, 9b ;						\
+	 mov	r3, r2
+
+/*
+ * Atomically increment an integer in memory.
+ */
+#define	ATOMIC_INC_INT(r1, r2, r3)					\
+	lduw	[r1], r2 ;						\
+9:	add	r2, 1, r3 ;						\
+	casa	[r1] ASI_N, r2, r3 ;					\
+	cmp	r2, r3 ;						\
+	bne,pn	%icc, 9b ;						\
+	 mov	r3, r2
+
+/*
+ * Atomically increment a long in memory.
+ */
+#define	ATOMIC_INC_LONG(r1, r2, r3)					\
+	ldx	[r1], r2 ;						\
+9:	add	r2, 1, r3 ;						\
+	casxa	[r1] ASI_N, r2, r3 ;					\
+	cmp	r2, r3 ;						\
+	bne,pn	%xcc, 9b ;						\
+	 mov	r3, r2
+
+/*
+ * Atomically clear a number of bits of an integer in memory.
+ */
+#define	ATOMIC_CLEAR_INT(r1, r2, r3, bits)				\
+	lduw	[r1], r2 ;						\
+9:	andn	r2, bits, r3 ;						\
+	casa	[r1] ASI_N, r2, r3 ;					\
+	cmp	r2, r3 ;						\
+	bne,pn	%icc, 9b ;						\
+	 mov	r3, r2
+
+/*
+ * Atomically clear a number of bits of a long in memory.
+ */
+#define	ATOMIC_CLEAR_LONG(r1, r2, r3, bits)				\
+	ldx	[r1], r2 ;						\
+9:	andn	r2, bits, r3 ;						\
+	casxa	[r1] ASI_N, r2, r3 ;					\
+	cmp	r2, r3 ;						\
+	bne,pn	%xcc, 9b ;						\
+	 mov	r3, r2
+
+/*
+ * Atomically load an integer from memory.
+ */
+#define	ATOMIC_LOAD_INT(r1, val)					\
+	clr	val ;							\
+	casa	[r1] ASI_N, %g0, val
+
+/*
+ * Atomically load a long from memory.
+ */
+#define	ATOMIC_LOAD_LONG(r1, val)					\
+	clr	val ;							\
+	casxa	[r1] ASI_N, %g0, val
+
+/*
+ * Atomically set a number of bits of an integer in memory.
+ */
+#define	ATOMIC_SET_INT(r1, r2, r3, bits)				\
+	lduw	[r1], r2 ;						\
+9:	or	r2, bits, r3 ;						\
+	casa	[r1] ASI_N, r2, r3 ;					\
+	cmp	r2, r3 ;						\
+	bne,pn	%icc, 9b ;						\
+	 mov	r3, r2
+
+/*
+ * Atomically set a number of bits of a long in memory.
+ */
+#define	ATOMIC_SET_LONG(r1, r2, r3, bits)				\
+	ldx	[r1], r2 ;						\
+9:	or	r2, bits, r3 ;						\
+	casxa	[r1] ASI_N, r2, r3 ;					\
+	cmp	r2, r3 ;						\
+	bne,pn	%xcc, 9b ;						\
+	 mov	r3, r2
+
+/*
+ * Atomically store an integer in memory.
+ */
+#define	ATOMIC_STORE_INT(r1, r2, r3, val)				\
+	lduw	[r1], r2 ;						\
+9:	mov	val, r3 ;						\
+	casa	[r1] ASI_N, r2, r3 ;					\
+	cmp	r2, r3 ;						\
+	bne,pn	%icc, 9b ;						\
+	 mov	r3, r2
+
+/*
+ * Atomically store a long in memory.
+ */
+#define	ATOMIC_STORE_LONG(r1, r2, r3, val)				\
+	ldx	[r1], r2 ;						\
+9:	mov	val, r3 ;						\
+	casxa	[r1] ASI_N, r2, r3 ;					\
+	cmp	r2, r3 ;						\
+	bne,pn	%xcc, 9b ;						\
+	 mov	r3, r2
+
+#define	PCPU(member)	PCPU_REG + PC_ ## member
+#define	PCPU_ADDR(member, reg)						\
+	add	PCPU_REG, PC_ ## member, reg
+
+#define	DEBUGGER()							\
+	ta	%xcc, 1
+
+#define	PANIC(msg, r1)							\
+	.sect	.rodata ;						\
+9:	.asciz	msg ;							\
+	.previous ;							\
+	SET(9b, r1, %o0) ;						\
+	call	panic ;							\
+	 nop
+
+#ifdef INVARIANTS
+#define	KASSERT(r1, msg)						\
+	brnz,pt	r1, 8f ;						\
+	 nop ;								\
+	PANIC(msg, r1) ;						\
+8:
+#else
+#define	KASSERT(r1, msg)
+#endif
+
+#define	PUTS(msg, r1)							\
+	.sect	.rodata ;						\
+9:	.asciz	msg ;							\
+	.previous ;							\
+	SET(9b, r1, %o0) ;						\
+	call	printf ;						\
+	 nop
+
+#define	_ALIGN_DATA	.align 8
+
+#define	DATA(name)							\
+	.data ;								\
+	_ALIGN_DATA ;							\
+	.globl	name ;							\
+	.type	name, @object ;						\
+name:
+
+#define	EMPTY
+
+/*
+ * Generate atomic compare and swap, load and store instructions for the
+ * corresponding width and ASI (or not).  Note that we want to evaluate the
+ * macro args before concatenating, so that EMPTY really turns into nothing.
+ */
+#define		_LD(w, a)	ld ## w ## a
+#define		_ST(w, a)	st ## w ## a
+#define		_CAS(w, a)	cas ## w ## a
+
+#define		LD(w, a)	_LD(w, a)
+#define		ST(w, a)	_ST(w, a)
+#define		CAS(w, a)	_CAS(w, a)
+
+#endif /* LOCORE */
+
+#endif /* _KERNEL */
+
+#endif /* !_MACHINE_ASMACROS_H_ */


Property changes on: trunk/sys/sparc64/include/asmacros.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/atomic.h
===================================================================
--- trunk/sys/sparc64/include/atomic.h	                        (rev 0)
+++ trunk/sys/sparc64/include/atomic.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,308 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1998 Doug Rabson.
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ *	from: FreeBSD: src/sys/i386/include/atomic.h,v 1.20 2001/02/11
+ * $FreeBSD: stable/10/sys/sparc64/include/atomic.h 253994 2013-08-06 15:34:11Z marius $
+ */
+
+#ifndef	_MACHINE_ATOMIC_H_
+#define	_MACHINE_ATOMIC_H_
+
+#include <machine/cpufunc.h>
+
+#define	mb()	__asm__ __volatile__ ("membar #MemIssue": : :"memory")
+#define	wmb()	mb()
+#define	rmb()	mb()
+
+/* Userland needs different ASI's. */
+#ifdef _KERNEL
+#define	__ASI_ATOMIC	ASI_N
+#else
+#define	__ASI_ATOMIC	ASI_P
+#endif
+
+/*
+ * Various simple arithmetic on memory which is atomic in the presence
+ * of interrupts and multiple processors.  See atomic(9) for details.
+ * Note that efficient hardware support exists only for the 32 and 64
+ * bit variants; the 8 and 16 bit versions are not provided and should
+ * not be used in MI code.
+ *
+ * This implementation takes advantage of the fact that the sparc64
+ * cas instruction is both a load and a store.  The loop is often coded
+ * as follows:
+ *
+ *	do {
+ *		expect = *p;
+ *		new = expect + 1;
+ *	} while (cas(p, expect, new) != expect);
+ *
+ * which performs an unnnecessary load on each iteration that the cas
+ * operation fails.  Modified as follows:
+ *
+ *	expect = *p;
+ *	for (;;) {
+ *		new = expect + 1;
+ *		result = cas(p, expect, new);
+ *		if (result == expect)
+ *			break;
+ *		expect = result;
+ *	}
+ *
+ * the return value of cas is used to avoid the extra reload.
+ *
+ * We only include a memory barrier in the rel variants as in total store
+ * order which we use for running the kernel and all of the userland atomic
+ * loads and stores behave as if the were followed by a membar with a mask
+ * of #LoadLoad | #LoadStore | #StoreStore.  In order to be also sufficient
+ * for use of relaxed memory ordering, the atomic_cas() in the acq variants
+ * additionally would have to be followed by a membar #LoadLoad | #LoadStore.
+ * Due to the suggested assembly syntax of the membar operands containing a
+ * # character, they cannot be used in macros.  The cmask and mmask bits thus
+ * are hard coded in machine/cpufunc.h and used here through macros.
+ * Hopefully the bit numbers won't change in the future.
+ */
+
+#define	itype(sz)	uint ## sz ## _t
+
+#define	atomic_cas_32(p, e, s)	casa((p), (e), (s), __ASI_ATOMIC)
+#define	atomic_cas_64(p, e, s)	casxa((p), (e), (s), __ASI_ATOMIC)
+
+#define	atomic_cas(p, e, s, sz)						\
+	atomic_cas_ ## sz((p), (e), (s))
+
+#define	atomic_cas_acq(p, e, s, sz) ({					\
+	itype(sz) v;							\
+	v = atomic_cas((p), (e), (s), sz);				\
+	__compiler_membar();						\
+	v;								\
+})
+
+#define	atomic_cas_rel(p, e, s, sz) ({					\
+	itype(sz) v;							\
+	membar(LoadStore | StoreStore);					\
+	v = atomic_cas((p), (e), (s), sz);				\
+	v;								\
+})
+
+#define	atomic_op(p, op, v, sz) ({					\
+	itype(sz) e, r, s;						\
+	for (e = *(volatile itype(sz) *)(p);; e = r) {			\
+		s = e op (v);						\
+		r = atomic_cas_ ## sz((p), e, s);			\
+		if (r == e)						\
+			break;						\
+	}								\
+	e;								\
+})
+
+#define	atomic_op_acq(p, op, v, sz) ({					\
+	itype(sz) t;							\
+	t = atomic_op((p), op, (v), sz);				\
+	__compiler_membar();						\
+	t;								\
+})
+
+#define	atomic_op_rel(p, op, v, sz) ({					\
+	itype(sz) t;							\
+	membar(LoadStore | StoreStore);					\
+	t = atomic_op((p), op, (v), sz);				\
+	t;								\
+})
+
+#define	atomic_ld_acq(p, sz) ({						\
+	itype(sz) v;							\
+	v = atomic_cas((p), 0, 0, sz);					\
+	__compiler_membar();						\
+	v;								\
+})
+
+#define	atomic_ld_clear(p, sz) ({					\
+	itype(sz) e, r;							\
+	for (e = *(volatile itype(sz) *)(p);; e = r) {			\
+		r = atomic_cas((p), e, 0, sz);				\
+		if (r == e)						\
+			break;						\
+	}								\
+	e;								\
+})
+
+#define	atomic_st(p, v, sz) do {					\
+	itype(sz) e, r;							\
+	for (e = *(volatile itype(sz) *)(p);; e = r) {			\
+		r = atomic_cas((p), e, (v), sz);			\
+		if (r == e)						\
+			break;						\
+	}								\
+} while (0)
+
+#define	atomic_st_acq(p, v, sz) do {					\
+	atomic_st((p), (v), sz);					\
+	__compiler_membar();						\
+} while (0)
+
+#define	atomic_st_rel(p, v, sz) do {					\
+	membar(LoadStore | StoreStore);					\
+	atomic_st((p), (v), sz);					\
+} while (0)
+
+#define	ATOMIC_GEN(name, ptype, vtype, atype, sz)			\
+									\
+static __inline vtype							\
+atomic_add_ ## name(volatile ptype p, atype v)				\
+{									\
+	return ((vtype)atomic_op((p), +, (v), sz));			\
+}									\
+static __inline vtype							\
+atomic_add_acq_ ## name(volatile ptype p, atype v)			\
+{									\
+	return ((vtype)atomic_op_acq((p), +, (v), sz));			\
+}									\
+static __inline vtype							\
+atomic_add_rel_ ## name(volatile ptype p, atype v)			\
+{									\
+	return ((vtype)atomic_op_rel((p), +, (v), sz));			\
+}									\
+									\
+static __inline vtype							\
+atomic_clear_ ## name(volatile ptype p, atype v)			\
+{									\
+	return ((vtype)atomic_op((p), &, ~(v), sz));			\
+}									\
+static __inline vtype							\
+atomic_clear_acq_ ## name(volatile ptype p, atype v)			\
+{									\
+	return ((vtype)atomic_op_acq((p), &, ~(v), sz));		\
+}									\
+static __inline vtype							\
+atomic_clear_rel_ ## name(volatile ptype p, atype v)			\
+{									\
+	return ((vtype)atomic_op_rel((p), &, ~(v), sz));		\
+}									\
+									\
+static __inline int							\
+atomic_cmpset_ ## name(volatile ptype p, vtype e, vtype s)		\
+{									\
+	return (((vtype)atomic_cas((p), (e), (s), sz)) == (e));		\
+}									\
+static __inline int							\
+atomic_cmpset_acq_ ## name(volatile ptype p, vtype e, vtype s)		\
+{									\
+	return (((vtype)atomic_cas_acq((p), (e), (s), sz)) == (e));	\
+}									\
+static __inline int							\
+atomic_cmpset_rel_ ## name(volatile ptype p, vtype e, vtype s)		\
+{									\
+	return (((vtype)atomic_cas_rel((p), (e), (s), sz)) == (e));	\
+}									\
+									\
+static __inline vtype							\
+atomic_load_ ## name(volatile ptype p)					\
+{									\
+	return ((vtype)atomic_cas((p), 0, 0, sz));			\
+}									\
+static __inline vtype							\
+atomic_load_acq_ ## name(volatile ptype p)				\
+{									\
+	return ((vtype)atomic_cas_acq((p), 0, 0, sz));			\
+}									\
+									\
+static __inline vtype							\
+atomic_readandclear_ ## name(volatile ptype p)				\
+{									\
+	return ((vtype)atomic_ld_clear((p), sz));			\
+}									\
+									\
+static __inline vtype							\
+atomic_set_ ## name(volatile ptype p, atype v)				\
+{									\
+	return ((vtype)atomic_op((p), |, (v), sz));			\
+}									\
+static __inline vtype							\
+atomic_set_acq_ ## name(volatile ptype p, atype v)			\
+{									\
+	return ((vtype)atomic_op_acq((p), |, (v), sz));			\
+}									\
+static __inline vtype							\
+atomic_set_rel_ ## name(volatile ptype p, atype v)			\
+{									\
+	return ((vtype)atomic_op_rel((p), |, (v), sz));			\
+}									\
+									\
+static __inline vtype							\
+atomic_subtract_ ## name(volatile ptype p, atype v)			\
+{									\
+	return ((vtype)atomic_op((p), -, (v), sz));			\
+}									\
+static __inline vtype							\
+atomic_subtract_acq_ ## name(volatile ptype p, atype v)			\
+{									\
+	return ((vtype)atomic_op_acq((p), -, (v), sz));			\
+}									\
+static __inline vtype							\
+atomic_subtract_rel_ ## name(volatile ptype p, atype v)			\
+{									\
+	return ((vtype)atomic_op_rel((p), -, (v), sz));			\
+}									\
+									\
+static __inline void							\
+atomic_store_acq_ ## name(volatile ptype p, vtype v)			\
+{									\
+	atomic_st_acq((p), (v), sz);					\
+}									\
+static __inline void							\
+atomic_store_rel_ ## name(volatile ptype p, vtype v)			\
+{									\
+	atomic_st_rel((p), (v), sz);					\
+}
+
+ATOMIC_GEN(int, u_int *, u_int, u_int, 32);
+ATOMIC_GEN(32, uint32_t *, uint32_t, uint32_t, 32);
+
+ATOMIC_GEN(long, u_long *, u_long, u_long, 64);
+ATOMIC_GEN(64, uint64_t *, uint64_t, uint64_t, 64);
+
+ATOMIC_GEN(ptr, uintptr_t *, uintptr_t, uintptr_t, 64);
+
+#define	atomic_fetchadd_int	atomic_add_int
+#define	atomic_fetchadd_32	atomic_add_32
+#define	atomic_fetchadd_long	atomic_add_long
+
+#undef ATOMIC_GEN
+#undef atomic_cas
+#undef atomic_cas_acq
+#undef atomic_cas_rel
+#undef atomic_op
+#undef atomic_op_acq
+#undef atomic_op_rel
+#undef atomic_ld_acq
+#undef atomic_ld_clear
+#undef atomic_st
+#undef atomic_st_acq
+#undef atomic_st_rel
+
+#endif /* !_MACHINE_ATOMIC_H_ */


Property changes on: trunk/sys/sparc64/include/atomic.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/bus.h
===================================================================
--- trunk/sys/sparc64/include/bus.h	                        (rev 0)
+++ trunk/sys/sparc64/include/bus.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,855 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1996, 1997, 1998, 2001 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.
+ *
+ * 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) 1997-1999 Eduardo E. Horvath. All rights reserved.
+ * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
+ * 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.
+ *
+ * 	from: NetBSD: bus.h,v 1.58 2008/04/28 20:23:36 martin Exp
+ *	and
+ *	from: FreeBSD: src/sys/alpha/include/bus.h,v 1.9 2001/01/09
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/bus.h 292308 2015-12-16 00:56:38Z marius $
+ */
+
+#ifndef	_MACHINE_BUS_H_
+#define	_MACHINE_BUS_H_
+
+#ifdef BUS_SPACE_DEBUG
+#include <sys/ktr.h>
+#endif
+
+#include <machine/_bus.h>
+#include <machine/cpufunc.h>
+
+/*
+ * Nexus and SBus spaces are non-cached and big endian
+ * (except for RAM and PROM)
+ *
+ * PCI spaces are non-cached and little endian
+ */
+#define	NEXUS_BUS_SPACE		0
+#define	SBUS_BUS_SPACE		1
+#define	PCI_CONFIG_BUS_SPACE	2
+#define	PCI_IO_BUS_SPACE	3
+#define	PCI_MEMORY_BUS_SPACE	4
+#define	LAST_BUS_SPACE		5
+
+extern const int bus_type_asi[];
+extern const int bus_stream_asi[];
+
+#define	__BUS_SPACE_HAS_STREAM_METHODS	1
+
+#define	BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
+#define	BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
+#define	BUS_SPACE_MAXSIZE	0xFFFFFFFFFFFFFFFF
+#define	BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
+#define	BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
+#define	BUS_SPACE_MAXADDR	0xFFFFFFFF
+
+#define	BUS_SPACE_UNRESTRICTED	(~0)
+
+struct bus_space_tag {
+	void		*bst_cookie;
+	bus_space_tag_t	bst_parent;
+	int		bst_type;
+
+	void		(*bst_bus_barrier)(bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, bus_size_t, int);
+};
+
+/*
+ * Bus space function prototypes.
+ */
+static void bus_space_barrier(bus_space_tag_t, bus_space_handle_t, bus_size_t,
+    bus_size_t, int);
+static int bus_space_subregion(bus_space_tag_t, bus_space_handle_t,
+    bus_size_t, bus_size_t, bus_space_handle_t *);
+
+/*
+ * Map a region of device bus space into CPU virtual address space.
+ */
+int bus_space_map(bus_space_tag_t tag, bus_addr_t address, bus_size_t size,
+    int flags, bus_space_handle_t *handlep);
+
+/*
+ * Unmap a region of device bus space.
+ */
+void bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t handle,
+    bus_size_t size);
+
+/* This macro finds the first "upstream" implementation of method `f' */
+#define	_BS_CALL(t,f)							\
+	while (t->f == NULL)						\
+		t = t->bst_parent;					\
+	return (*(t)->f)
+
+static __inline void
+bus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    bus_size_t s, int f)
+{
+
+	_BS_CALL(t, bst_bus_barrier)(t, h, o, s, f);
+}
+
+static __inline int
+bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t h,
+    bus_size_t o __unused, bus_size_t s __unused, bus_space_handle_t *hp)
+{
+
+	*hp = h + o;
+	return (0);
+}
+
+/* flags for bus space map functions */
+#define	BUS_SPACE_MAP_CACHEABLE		0x0001
+#define	BUS_SPACE_MAP_LINEAR		0x0002
+#define	BUS_SPACE_MAP_READONLY		0x0004
+#define	BUS_SPACE_MAP_PREFETCHABLE	0x0008
+/* placeholders for bus functions... */
+#define	BUS_SPACE_MAP_BUS1		0x0100
+#define	BUS_SPACE_MAP_BUS2		0x0200
+#define	BUS_SPACE_MAP_BUS3		0x0400
+#define	BUS_SPACE_MAP_BUS4		0x0800
+
+/* flags for bus_space_barrier() */
+#define	BUS_SPACE_BARRIER_READ		0x01	/* force read barrier */
+#define	BUS_SPACE_BARRIER_WRITE		0x02	/* force write barrier */
+
+#ifdef BUS_SPACE_DEBUG
+#define	KTR_BUS				KTR_SPARE2
+#define	__BUS_DEBUG_ACCESS(h, o, desc, sz) do {				\
+	CTR4(KTR_BUS, "bus space: %s %d: handle %#lx, offset %#lx",	\
+	    (desc), (sz), (h), (o));					\
+} while (0)
+#else
+#define	__BUS_DEBUG_ACCESS(h, o, desc, sz)
+#endif
+
+static __inline uint8_t
+bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "read", 1);
+	return (lduba_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
+}
+
+static __inline uint16_t
+bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "read", 2);
+	return (lduha_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
+}
+
+static __inline uint32_t
+bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "read", 4);
+	return (lduwa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
+}
+
+static __inline uint64_t
+bus_space_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "read", 8);
+	return (ldxa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
+}
+
+static __inline void
+bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint8_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		*a++ = bus_space_read_1(t, h, o);
+}
+
+static __inline void
+bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint16_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		*a++ = bus_space_read_2(t, h, o);
+}
+
+static __inline void
+bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint32_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		*a++ = bus_space_read_4(t, h, o);
+}
+
+static __inline void
+bus_space_read_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint64_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		*a++ = bus_space_read_8(t, h, o);
+}
+
+static __inline void
+bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint8_t v)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "write", 1);
+	stba_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
+}
+
+static __inline void
+bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint16_t v)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "write", 2);
+	stha_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
+}
+
+static __inline void
+bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint32_t v)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "write", 4);
+	stwa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
+}
+
+static __inline void
+bus_space_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint64_t v)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "write", 8);
+	stxa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
+}
+
+static __inline void
+bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint8_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_1(t, h, o, *a++);
+}
+
+static __inline void
+bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint16_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_2(t, h, o, *a++);
+}
+
+static __inline void
+bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint32_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_4(t, h, o, *a++);
+}
+
+static __inline void
+bus_space_write_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint64_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_8(t, h, o, *a++);
+}
+
+static __inline void
+bus_space_set_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint8_t v, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_1(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint16_t v, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_2(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint32_t v, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_4(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint64_t v, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_8(t, h, o, v);
+}
+
+static __inline void
+bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint8_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o++)
+		*a = bus_space_read_1(t, h, o);
+}
+
+static __inline void
+bus_space_read_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint16_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 2)
+		*a = bus_space_read_2(t, h, o);
+}
+
+static __inline void
+bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint32_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 4)
+		*a = bus_space_read_4(t, h, o);
+}
+
+static __inline void
+bus_space_read_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint64_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 8)
+		*a = bus_space_read_8(t, h, o);
+}
+
+static __inline void
+bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint8_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o++)
+		bus_space_write_1(t, h, o, *a);
+}
+
+static __inline void
+bus_space_write_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint16_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 2)
+		bus_space_write_2(t, h, o, *a);
+}
+
+static __inline void
+bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint32_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 4)
+		bus_space_write_4(t, h, o, *a);
+}
+
+static __inline void
+bus_space_write_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint64_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 8)
+		bus_space_write_8(t, h, o, *a);
+}
+
+static __inline void
+bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint8_t v, bus_size_t c)
+{
+
+	for (; c; c--, o++)
+		bus_space_write_1(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint16_t v, bus_size_t c)
+{
+
+	for (; c; c--, o += 2)
+		bus_space_write_2(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint32_t v, bus_size_t c)
+{
+
+	for (; c; c--, o += 4)
+		bus_space_write_4(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    const uint64_t v, bus_size_t c)
+{
+
+	for (; c; c--, o += 8)
+		bus_space_write_8(t, h, o, v);
+}
+
+static __inline void
+bus_space_copy_region_1(bus_space_tag_t t, bus_space_handle_t h1,
+    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+
+	for (; c; c--, o1++, o2++)
+	    bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2));
+}
+
+static __inline void
+bus_space_copy_region_2(bus_space_tag_t t, bus_space_handle_t h1,
+    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+
+	for (; c; c--, o1 += 2, o2 += 2)
+	    bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2));
+}
+
+static __inline void
+bus_space_copy_region_4(bus_space_tag_t t, bus_space_handle_t h1,
+    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+
+	for (; c; c--, o1 += 4, o2 += 4)
+	    bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2));
+}
+
+static __inline void
+bus_space_copy_region_8(bus_space_tag_t t, bus_space_handle_t h1,
+    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+
+	for (; c; c--, o1 += 8, o2 += 8)
+	    bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2));
+}
+
+static __inline uint8_t
+bus_space_read_stream_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "read stream", 1);
+	return (lduba_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
+}
+
+static __inline uint16_t
+bus_space_read_stream_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "read stream", 2);
+	return (lduha_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
+}
+
+static __inline uint32_t
+bus_space_read_stream_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "read stream", 4);
+	return (lduwa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
+}
+
+static __inline uint64_t
+bus_space_read_stream_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "read stream", 8);
+	return (ldxa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
+}
+
+static __inline void
+bus_space_read_multi_stream_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint8_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		*a++ = bus_space_read_stream_1(t, h, o);
+}
+
+static __inline void
+bus_space_read_multi_stream_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint16_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		*a++ = bus_space_read_stream_2(t, h, o);
+}
+
+static __inline void
+bus_space_read_multi_stream_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint32_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		*a++ = bus_space_read_stream_4(t, h, o);
+}
+
+static __inline void
+bus_space_read_multi_stream_8(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint64_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		*a++ = bus_space_read_stream_8(t, h, o);
+}
+
+static __inline void
+bus_space_write_stream_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint8_t v)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "write stream", 1);
+	stba_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
+}
+
+static __inline void
+bus_space_write_stream_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint16_t v)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "write stream", 2);
+	stha_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
+}
+
+static __inline void
+bus_space_write_stream_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint32_t v)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "write stream", 4);
+	stwa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
+}
+
+static __inline void
+bus_space_write_stream_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+    uint64_t v)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "write stream", 8);
+	stxa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
+}
+
+static __inline void
+bus_space_write_multi_stream_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint8_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_stream_1(t, h, o, *a++);
+}
+
+static __inline void
+bus_space_write_multi_stream_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint16_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_stream_2(t, h, o, *a++);
+}
+
+static __inline void
+bus_space_write_multi_stream_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint32_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_stream_4(t, h, o, *a++);
+}
+
+static __inline void
+bus_space_write_multi_stream_8(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint64_t *a, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_stream_8(t, h, o, *a++);
+}
+
+static __inline void
+bus_space_set_multi_stream_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint8_t v, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_stream_1(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_multi_stream_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint16_t v, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_stream_2(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_multi_stream_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint32_t v, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_stream_4(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_multi_stream_8(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint64_t v, size_t c)
+{
+
+	while (c-- > 0)
+		bus_space_write_stream_8(t, h, o, v);
+}
+
+static __inline void
+bus_space_read_region_stream_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint8_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o++)
+		*a = bus_space_read_stream_1(t, h, o);
+}
+
+static __inline void
+bus_space_read_region_stream_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint16_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 2)
+		*a = bus_space_read_stream_2(t, h, o);
+}
+
+static __inline void
+bus_space_read_region_stream_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint32_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 4)
+		*a = bus_space_read_stream_4(t, h, o);
+}
+
+static __inline void
+bus_space_read_region_stream_8(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, uint64_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 8)
+		*a = bus_space_read_stream_8(t, h, o);
+}
+
+static __inline void
+bus_space_write_region_stream_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint8_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o++)
+		bus_space_write_stream_1(t, h, o, *a);
+}
+
+static __inline void
+bus_space_write_region_stream_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint16_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 2)
+		bus_space_write_stream_2(t, h, o, *a);
+}
+
+static __inline void
+bus_space_write_region_stream_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint32_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 4)
+		bus_space_write_stream_4(t, h, o, *a);
+}
+
+static __inline void
+bus_space_write_region_stream_8(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint64_t *a, bus_size_t c)
+{
+
+	for (; c; a++, c--, o += 8)
+		bus_space_write_stream_8(t, h, o, *a);
+}
+
+static __inline void
+bus_space_set_region_stream_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint8_t v, bus_size_t c)
+{
+
+	for (; c; c--, o++)
+		bus_space_write_stream_1(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_region_stream_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint16_t v, bus_size_t c)
+{
+
+	for (; c; c--, o += 2)
+		bus_space_write_stream_2(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_region_stream_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint32_t v, bus_size_t c)
+{
+
+	for (; c; c--, o += 4)
+		bus_space_write_stream_4(t, h, o, v);
+}
+
+static __inline void
+bus_space_set_region_stream_8(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t o, const uint64_t v, bus_size_t c)
+{
+
+	for (; c; c--, o += 8)
+		bus_space_write_stream_8(t, h, o, v);
+}
+
+static __inline void
+bus_space_copy_region_stream_1(bus_space_tag_t t, bus_space_handle_t h1,
+    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+
+	for (; c; c--, o1++, o2++)
+	    bus_space_write_stream_1(t, h1, o1, bus_space_read_stream_1(t, h2,
+		o2));
+}
+
+static __inline void
+bus_space_copy_region_stream_2(bus_space_tag_t t, bus_space_handle_t h1,
+    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+
+	for (; c; c--, o1 += 2, o2 += 2)
+	    bus_space_write_stream_2(t, h1, o1, bus_space_read_stream_2(t, h2,
+		o2));
+}
+
+static __inline void
+bus_space_copy_region_stream_4(bus_space_tag_t t, bus_space_handle_t h1,
+    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+
+	for (; c; c--, o1 += 4, o2 += 4)
+	    bus_space_write_stream_4(t, h1, o1, bus_space_read_stream_4(t, h2,
+		o2));
+}
+
+static __inline void
+bus_space_copy_region_stream_8(bus_space_tag_t t, bus_space_handle_t h1,
+    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+
+	for (; c; c--, o1 += 8, o2 += 8)
+	    bus_space_write_stream_8(t, h1, o1, bus_space_read_8(t, h2, o2));
+}
+
+static __inline int
+bus_space_peek_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+	uint8_t *a)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "peek", 1);
+	return (fasword8(bus_type_asi[t->bst_type], (caddr_t)(h + o), a));
+}
+
+static __inline int
+bus_space_peek_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+	uint16_t *a)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "peek", 2);
+	return (fasword16(bus_type_asi[t->bst_type], (caddr_t)(h + o), a));
+}
+
+static __inline int
+bus_space_peek_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+	uint32_t *a)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "peek", 4);
+	return (fasword32(bus_type_asi[t->bst_type], (caddr_t)(h + o), a));
+}
+
+#include <machine/bus_dma.h>
+
+#endif /* !_MACHINE_BUS_H_ */


Property changes on: trunk/sys/sparc64/include/bus.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/bus_common.h
===================================================================
--- trunk/sys/sparc64/include/bus_common.h	                        (rev 0)
+++ trunk/sys/sparc64/include/bus_common.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,76 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 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.
+ *
+ *	form: @(#)sbusreg.h	8.1 (Berkeley) 6/11/93
+ *	from: NetBSD: iommureg.h,v 1.6 2001/07/20 00:07:13 eeh Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/bus_common.h 200878 2009-12-22 21:48:18Z marius $
+ */
+
+#ifndef _MACHINE_BUS_COMMON_H_
+#define	_MACHINE_BUS_COMMON_H_
+
+#define	INTCLR_PENDING		0x000000003ULL	/* Interrupt queued to CPU */
+#define	INTCLR_RECEIVED		0x000000001ULL	/* Interrupt received */
+#define	INTCLR_IDLE		0x000000000ULL	/* Interrupt idle */
+
+#define	INTMAP_V		0x080000000ULL	/* Interrupt valid (enabled) */
+#define	INTMAP_TID_MASK		0x07c000000ULL	/* UPA target ID */
+#define	INTMAP_TID_SHIFT	26
+#define	INTMAP_IGN_MASK		0x0000007c0ULL	/* Interrupt group no. */
+#define	INTMAP_IGN_SHIFT	6
+#define	INTMAP_INO_MASK		0x00000003fULL	/* Interrupt number */
+#define	INTMAP_INR_MASK		(INTMAP_IGN_MASK | INTMAP_INO_MASK)
+#define	INTMAP_SBUSSLOT_MASK	0x000000018ULL	/* SBus slot # */
+#define	INTMAP_PCIBUS_MASK	0x000000010ULL	/* PCI bus number (A or B) */
+#define	INTMAP_PCISLOT_MASK	0x00000000cULL	/* PCI slot # */
+#define	INTMAP_PCIINT_MASK	0x000000003ULL	/* PCI interrupt #A,#B,#C,#D */
+#define	INTMAP_OBIO_MASK	0x000000020ULL	/* Onboard device */
+#define	INTIGN(x)		(((x) & INTMAP_IGN_MASK) >> INTMAP_IGN_SHIFT)
+#define	INTVEC(x)		((x) & INTMAP_INR_MASK)
+#define	INTSLOT(x)		(((x) >> 3) & 0x7)
+#define	INTPRI(x)		((x) & 0x7)
+#define	INTINO(x)		((x) & INTMAP_INO_MASK)
+#define	INTMAP_ENABLE(mr, mid)						\
+	(INTMAP_TID((mr), (mid)) | INTMAP_V)
+#define	INTMAP_TID(mr, mid)						\
+	(((mr) & ~INTMAP_TID_MASK) | ((mid) << INTMAP_TID_SHIFT))
+#define	INTMAP_VEC(ign, ino)						\
+	((((ign) << INTMAP_IGN_SHIFT) & INTMAP_IGN_MASK) |		\
+	((ino) & INTMAP_INO_MASK))
+
+/* counter-timer support. */
+void sparc64_counter_init(const char *name, bus_space_tag_t tag,
+    bus_space_handle_t handle, bus_addr_t offset);
+
+#endif	/* !_MACHINE_BUS_COMMON_H_ */


Property changes on: trunk/sys/sparc64/include/bus_common.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/bus_dma.h
===================================================================
--- trunk/sys/sparc64/include/bus_dma.h	                        (rev 0)
+++ trunk/sys/sparc64/include/bus_dma.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,153 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1996, 1997, 1998, 2001 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.
+ *
+ * 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) 1997-1999 Eduardo E. Horvath. All rights reserved.
+ * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
+ * 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.
+ *
+ * 	from: NetBSD: bus.h,v 1.58 2008/04/28 20:23:36 martin Exp
+ *	and
+ *	from: FreeBSD: src/sys/alpha/include/bus.h,v 1.9 2001/01/09
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/bus_dma.h 259510 2013-12-17 13:38:21Z kib $
+ */
+
+#ifndef _SPARC64_BUS_DMA_H
+#define _SPARC64_BUS_DMA_H
+
+#include <sys/bus_dma.h>
+
+/* DMA support */
+
+/*
+ * Method table for a bus_dma_tag.
+ */
+struct bus_dma_methods {
+	int	(*dm_dmamap_create)(bus_dma_tag_t, int, bus_dmamap_t *);
+	int	(*dm_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
+	int	(*dm_dmamap_load_phys)(bus_dma_tag_t dmat, bus_dmamap_t map,
+	    vm_paddr_t buf, bus_size_t buflen, int flags,
+	    bus_dma_segment_t *segs, int *segp);
+	int	(*dm_dmamap_load_buffer)(bus_dma_tag_t dmat, bus_dmamap_t map,
+	    void *buf, bus_size_t buflen, struct pmap *pmap, int flags,
+	    bus_dma_segment_t *segs, int *segp);
+	void	(*dm_dmamap_waitok)(bus_dma_tag_t dmat, bus_dmamap_t map,
+	    struct memdesc *mem, bus_dmamap_callback_t *callback,
+	    void *callback_arg);
+	bus_dma_segment_t *(*dm_dmamap_complete)(bus_dma_tag_t dmat,
+	    bus_dmamap_t map, bus_dma_segment_t *segs, int nsegs, int error);
+	void	(*dm_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
+	void	(*dm_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
+	    bus_dmasync_op_t);
+	int	(*dm_dmamem_alloc)(bus_dma_tag_t, void **, int, bus_dmamap_t *);
+	void	(*dm_dmamem_free)(bus_dma_tag_t, void *, bus_dmamap_t);
+};
+
+/*
+ * bus_dma_tag_t
+ *
+ * A machine-dependent opaque type describing the implementation of
+ * DMA for a given bus.
+ */
+struct bus_dma_tag {
+	void		*dt_cookie;		/* cookie used in the guts */
+	bus_dma_tag_t	dt_parent;
+	bus_size_t	dt_alignment;
+	bus_addr_t	dt_boundary;
+	bus_addr_t	dt_lowaddr;
+	bus_addr_t	dt_highaddr;
+	bus_dma_filter_t	*dt_filter;
+	void		*dt_filterarg;
+	bus_size_t	dt_maxsize;
+	int		dt_nsegments;
+	bus_size_t	dt_maxsegsz;
+	int		dt_flags;
+	int		dt_ref_count;
+	int		dt_map_count;
+	bus_dma_lock_t	*dt_lockfunc;
+	void *		*dt_lockfuncarg;
+	bus_dma_segment_t *dt_segments;
+
+	struct bus_dma_methods	*dt_mt;
+};
+
+#define	bus_dmamap_create(t, f, p)					\
+	((t)->dt_mt->dm_dmamap_create((t), (f), (p)))
+#define	bus_dmamap_destroy(t, p)					\
+	((t)->dt_mt->dm_dmamap_destroy((t), (p)))
+#define	_bus_dmamap_load_phys(t, m, b, l, f, s, sp)			\
+	((t)->dt_mt->dm_dmamap_load_phys((t), (m), (b), (l),		\
+	    (f), (s), (sp)))
+#define	_bus_dmamap_load_buffer(t, m, b, l, p, f, s, sp)		\
+	((t)->dt_mt->dm_dmamap_load_buffer((t), (m), (b), (l), (p),	\
+	    (f), (s), (sp)))
+#define	_bus_dmamap_waitok(t, m, mem, c, ca)				\
+	((t)->dt_mt->dm_dmamap_waitok((t), (m), (mem), (c), (ca)))
+#define	_bus_dmamap_complete(t, m, s, n, e)				\
+	((t)->dt_mt->dm_dmamap_complete((t), (m), (s), (n), (e)))
+#define	bus_dmamap_unload(t, p)						\
+	((t)->dt_mt->dm_dmamap_unload((t), (p)))
+#define	bus_dmamap_sync(t, m, op)					\
+	((t)->dt_mt->dm_dmamap_sync((t), (m), (op)))
+#define	bus_dmamem_alloc(t, v, f, m)					\
+	((t)->dt_mt->dm_dmamem_alloc((t), (v), (f), (m)))
+#define	bus_dmamem_free(t, v, m)					\
+	((t)->dt_mt->dm_dmamem_free((t), (v), (m)))
+#define _bus_dmamap_load_ma(t, m, a, tt, o, f, s, p)			\
+	bus_dmamap_load_ma_triv((t), (m), (a), (tt), (o), (f), (s), (p))
+
+#endif /* !_SPARC64_BUS_DMA_H_ */


Property changes on: trunk/sys/sparc64/include/bus_dma.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/bus_private.h
===================================================================
--- trunk/sys/sparc64/include/bus_private.h	                        (rev 0)
+++ trunk/sys/sparc64/include/bus_private.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,82 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1997, 1998 Justin T. Gibbs.
+ * Copyright (c) 2002 by Thomas Moestl <tmm at 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, 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 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: FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.25 2002/01/05
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/bus_private.h 225931 2011-10-02 23:22:38Z marius $
+ */
+
+#ifndef	_MACHINE_BUS_PRIVATE_H_
+#define	_MACHINE_BUS_PRIVATE_H_
+
+#include <sys/queue.h>
+
+/*
+ * Helpers
+ */
+int sparc64_bus_mem_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size,
+    int flags, vm_offset_t vaddr, bus_space_handle_t *hp);
+int sparc64_bus_mem_unmap(bus_space_tag_t tag, bus_space_handle_t handle,
+    bus_size_t size);
+bus_space_tag_t sparc64_alloc_bus_tag(void *cookie,
+    struct bus_space_tag *ptag, int type, void *barrier);
+bus_space_handle_t sparc64_fake_bustag(int space, bus_addr_t addr,
+    struct bus_space_tag *ptag);
+
+struct bus_dmamap_res {
+	struct resource		*dr_res;
+	bus_size_t		dr_used;
+	SLIST_ENTRY(bus_dmamap_res)	dr_link;
+};
+
+/*
+ * Callers of the bus_dma interfaces must always protect their tags and maps
+ * appropriately against concurrent access. However, when a map is on a LRU
+ * queue, there is a second access path to it; for this case, the locking rules
+ * are given in the parenthesized comments below:
+ *	q - locked by the mutex protecting the queue.
+ *	p - private to the owner of the map, no access through the queue.
+ *	* - comment refers to pointer target.
+ * Only the owner of the map is allowed to insert the map into a queue. Removal
+ * and repositioning (i.e. temporal removal and reinsertion) is allowed to all
+ * if the queue lock is held.
+ */
+struct bus_dmamap {
+	TAILQ_ENTRY(bus_dmamap)	dm_maplruq;		/* (q) */
+	SLIST_HEAD(, bus_dmamap_res)	dm_reslist;	/* (q, *q) */
+	int			dm_onq;			/* (q) */
+	int			dm_flags;		/* (p) */
+};
+
+/* Flag values */
+#define	DMF_LOADED	(1 << 0)	/* Map is loaded. */
+#define	DMF_COHERENT	(1 << 1)	/* Coherent mapping requested. */
+#define	DMF_STREAMED	(1 << 2)	/* Streaming cache used. */
+
+int sparc64_dma_alloc_map(bus_dma_tag_t dmat, bus_dmamap_t *mapp);
+void sparc64_dma_free_map(bus_dma_tag_t dmat, bus_dmamap_t map);
+
+#endif /* !_MACHINE_BUS_PRIVATE_H_ */


Property changes on: trunk/sys/sparc64/include/bus_private.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/cache.h
===================================================================
--- trunk/sys/sparc64/include/cache.h	                        (rev 0)
+++ trunk/sys/sparc64/include/cache.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,128 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1996
+ *	The President and Fellows of Harvard College. All rights reserved.
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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 Aaron Brown and
+ *	Harvard University.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: @(#)cache.h	8.1 (Berkeley) 6/11/93
+ *	from: NetBSD: cache.h,v 1.3 2000/08/01 00:28:02 eeh Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/cache.h 223719 2011-07-02 11:14:54Z marius $
+ */
+
+#ifndef _MACHINE_CACHE_H_
+#define	_MACHINE_CACHE_H_
+
+#define	DCACHE_COLOR_BITS	(1)
+#define	DCACHE_COLORS		(1 << DCACHE_COLOR_BITS)
+#define	DCACHE_COLOR_MASK	(DCACHE_COLORS - 1)
+#define	DCACHE_COLOR(va)	(((va) >> PAGE_SHIFT) & DCACHE_COLOR_MASK)
+#define	DCACHE_OTHER_COLOR(color)					\
+	((color) ^ DCACHE_COLOR_BITS)
+
+#define	DC_TAG_SHIFT	2
+#define	DC_VALID_SHIFT	0
+
+#define	DC_TAG_BITS	28
+#define	DC_VALID_BITS	2
+
+#define	DC_TAG_MASK	((1 << DC_TAG_BITS) - 1)
+#define	DC_VALID_MASK	((1 << DC_VALID_BITS) - 1)
+
+#define	IC_TAG_SHIFT	7
+#define	IC_VALID_SHIFT	36
+
+#define	IC_TAG_BITS	28
+#define	IC_VALID_BITS	1
+
+#define	IC_TAG_MASK	((1 << IC_TAG_BITS) - 1)
+#define	IC_VALID_MASK	((1 << IC_VALID_BITS) - 1)
+
+#ifndef LOCORE
+
+/*
+ * Cache control information
+ */
+struct cacheinfo {
+	u_int	ic_size;		/* instruction cache */
+	u_int	ic_assoc;
+	u_int	ic_linesize;
+	u_int	dc_size;		/* data cache */
+	u_int	dc_assoc;
+	u_int	dc_linesize;
+	u_int	ec_size;		/* external cache info */
+	u_int	ec_assoc;
+	u_int	ec_linesize;
+};
+
+#ifdef _KERNEL
+
+extern u_int dcache_color_ignore;
+
+struct pcpu;
+
+typedef void cache_enable_t(u_int cpu_impl);
+typedef void cache_flush_t(void);
+typedef void dcache_page_inval_t(vm_paddr_t pa);
+typedef void icache_page_inval_t(vm_paddr_t pa);
+
+void cache_init(struct pcpu *pcpu);
+
+cache_enable_t cheetah_cache_enable;
+cache_flush_t cheetah_cache_flush;
+dcache_page_inval_t cheetah_dcache_page_inval;
+icache_page_inval_t cheetah_icache_page_inval;
+
+cache_enable_t spitfire_cache_enable;
+cache_flush_t spitfire_cache_flush;
+dcache_page_inval_t spitfire_dcache_page_inval;
+icache_page_inval_t spitfire_icache_page_inval;
+
+cache_enable_t zeus_cache_enable;
+cache_flush_t zeus_cache_flush;
+dcache_page_inval_t zeus_dcache_page_inval;
+icache_page_inval_t zeus_icache_page_inval;
+
+extern cache_enable_t *cache_enable;
+extern cache_flush_t *cache_flush;
+extern dcache_page_inval_t *dcache_page_inval;
+extern icache_page_inval_t *icache_page_inval;
+
+#endif /* KERNEL */
+
+#endif /* !LOCORE */
+
+#endif /* !_MACHINE_CACHE_H_ */


Property changes on: trunk/sys/sparc64/include/cache.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/ccr.h
===================================================================
--- trunk/sys/sparc64/include/ccr.h	                        (rev 0)
+++ trunk/sys/sparc64/include/ccr.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,47 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2001 by Thomas Moestl <tmm at 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, 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 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/ccr.h 88618 2001-12-29 06:50:25Z jake $
+ */
+
+#ifndef	_MACHINE_CCR_H_
+#define	_MACHINE_CCR_H_
+
+#define	ICC_SHIFT	0
+#define	ICC_BITS	4
+#define	ICC_MASK	((1UL << ICC_BITS) - 1)
+#define	ICC_C		(1UL << 0)
+#define	ICC_V		(1UL << 1)
+#define	ICC_Z		(1UL << 2)
+#define	ICC_N		(1UL << 3)
+
+#define	XCC_SHIFT	4
+#define	XCC_BITS	4
+#define	XCC_MASK	(((1UL << XCC_BITS) - 1) << XCC_SHIFT)
+#define	XCC_C		(1UL << 4)
+#define	XCC_V		(1UL << 5)
+#define	XCC_Z		(1UL << 6)
+#define	XCC_N		(1UL << 7)
+
+#endif /* !_MACHINE_CCR_H_ */


Property changes on: trunk/sys/sparc64/include/ccr.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/clock.h
===================================================================
--- trunk/sys/sparc64/include/clock.h	                        (rev 0)
+++ trunk/sys/sparc64/include/clock.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,11 @@
+/* $MidnightBSD$ */
+/*-
+ * This file is in the public domain.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/clock.h 230633 2012-01-27 23:21:54Z marius $
+ */
+
+#ifndef	_MACHINE_CLOCK_H_
+#define	_MACHINE_CLOCK_H_
+
+#endif /* !_MACHINE_CLOCK_H_ */


Property changes on: trunk/sys/sparc64/include/clock.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/cmt.h
===================================================================
--- trunk/sys/sparc64/include/cmt.h	                        (rev 0)
+++ trunk/sys/sparc64/include/cmt.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,40 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Marius Strobl <marius at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/cmt.h 203829 2010-02-13 14:13:39Z marius $
+ */
+
+#ifndef _MACHINE_CMT_H_
+#define	_MACHINE_CMT_H_
+
+#define	INTR_ID_ID_SHIFT	(0)
+#define	INTR_ID_ID_SIZE		(10)
+#define	INTR_ID_ID_MASK							\
+	(((1 << INTR_ID_ID_SIZE) - 1) << INTR_ID_ID_SHIFT)
+
+#define	INTR_ID_GET_ID(cr)	((cr & INTR_ID_ID_MASK) >> INTR_ID_ID_SHIFT)
+
+#endif /* _MACHINE_CMT_H_ */


Property changes on: trunk/sys/sparc64/include/cmt.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/counter.h
===================================================================
--- trunk/sys/sparc64/include/counter.h	                        (rev 0)
+++ trunk/sys/sparc64/include/counter.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,94 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Konstantin Belousov <kib at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/counter.h 252434 2013-07-01 02:48:27Z kib $
+ */
+
+#ifndef __MACHINE_COUNTER_H__
+#define __MACHINE_COUNTER_H__
+
+#include <sys/pcpu.h>
+#ifdef INVARIANTS
+#include <sys/proc.h>
+#endif
+
+#define	counter_enter()	critical_enter()
+#define	counter_exit()	critical_exit()
+
+#ifdef IN_SUBR_COUNTER_C
+static inline uint64_t
+counter_u64_read_one(uint64_t *p, int cpu)
+{
+
+	return (*(uint64_t *)((char *)p + sizeof(struct pcpu) * cpu));
+}
+
+static inline uint64_t
+counter_u64_fetch_inline(uint64_t *p)
+{
+	uint64_t r;
+	int i;
+
+	r = 0;
+	for (i = 0; i < mp_ncpus; i++)
+		r += counter_u64_read_one((uint64_t *)p, i);
+
+	return (r);
+}
+
+/* XXXKIB might interrupt increment */
+static void
+counter_u64_zero_one_cpu(void *arg)
+{
+
+	*((uint64_t *)((char *)arg + sizeof(struct pcpu) *
+	    PCPU_GET(cpuid))) = 0;
+}
+
+static inline void
+counter_u64_zero_inline(counter_u64_t c)
+{
+
+	smp_rendezvous(smp_no_rendevous_barrier, counter_u64_zero_one_cpu,
+	    smp_no_rendevous_barrier, c);
+}
+#endif
+
+#define	counter_u64_add_protected(c, inc)	do {	\
+	CRITICAL_ASSERT(curthread);			\
+	*(uint64_t *)zpcpu_get(c) += (inc);		\
+} while (0)
+
+static inline void
+counter_u64_add(counter_u64_t c, int64_t inc)
+{
+
+	counter_enter();
+	counter_u64_add_protected(c, inc);
+	counter_exit();
+}
+
+#endif	/* ! __MACHINE_COUNTER_H__ */


Property changes on: trunk/sys/sparc64/include/counter.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/cpu.h
===================================================================
--- trunk/sys/sparc64/include/cpu.h	                        (rev 0)
+++ trunk/sys/sparc64/include/cpu.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,72 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 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: @(#)cpu.h 5.4 (Berkeley) 5/9/91
+ *	from: FreeBSD: src/sys/i386/include/cpu.h,v 1.62 2001/06/29
+ * $FreeBSD: stable/10/sys/sparc64/include/cpu.h 253750 2013-07-28 18:44:17Z avg $
+ */
+
+#ifndef	_MACHINE_CPU_H_
+#define	_MACHINE_CPU_H_
+
+#include <machine/frame.h>
+#include <machine/tstate.h>
+
+#define	TRAPF_PC(tfp)		((tfp)->tf_tpc)
+#define	TRAPF_USERMODE(tfp)	(((tfp)->tf_tstate & TSTATE_PRIV) == 0)
+
+#define	cpu_getstack(td)	((td)->td_frame->tf_sp)
+#define	cpu_setstack(td, sp)	((td)->td_frame->tf_sp = (sp))
+#define	cpu_spinwait()		/* nothing */
+
+#ifdef _KERNEL
+
+extern	char btext[];
+extern	char etext[];
+
+void	cheetah_init(u_int cpu_impl);
+void	cpu_halt(void) __dead2;
+void	cpu_reset(void) __dead2;
+void	fork_trampoline(void);
+void	swi_vm(void *v);
+void	zeus_init(u_int cpu_impl);
+
+static __inline u_int64_t
+get_cyclecount(void)
+{
+
+	return (rd(tick));
+}
+
+#endif
+
+#endif /* !_MACHINE_CPU_H_ */


Property changes on: trunk/sys/sparc64/include/cpu.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/cpufunc.h
===================================================================
--- trunk/sys/sparc64/include/cpufunc.h	                        (rev 0)
+++ trunk/sys/sparc64/include/cpufunc.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,271 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/cpufunc.h 220939 2011-04-22 09:31:40Z marius $
+ */
+
+#ifndef	_MACHINE_CPUFUNC_H_
+#define	_MACHINE_CPUFUNC_H_
+
+#include <machine/asi.h>
+#include <machine/pstate.h>
+
+struct thread;
+
+/*
+ * Membar operand macros for use in other macros when # is a special
+ * character.  Keep these in sync with what the hardware expects.
+ */
+#define	C_Lookaside	(0)
+#define	C_MemIssue	(1)
+#define	C_Sync		(2)
+#define	M_LoadLoad	(0)
+#define	M_StoreLoad	(1)
+#define	M_LoadStore	(2)
+#define	M_StoreStore	(3)
+
+#define	CMASK_SHIFT	(4)
+#define	MMASK_SHIFT	(0)
+
+#define	CMASK_GEN(bit)	((1 << (bit)) << CMASK_SHIFT)
+#define	MMASK_GEN(bit)	((1 << (bit)) << MMASK_SHIFT)
+
+#define	Lookaside	CMASK_GEN(C_Lookaside)
+#define	MemIssue	CMASK_GEN(C_MemIssue)
+#define	Sync		CMASK_GEN(C_Sync)
+#define	LoadLoad	MMASK_GEN(M_LoadLoad)
+#define	StoreLoad	MMASK_GEN(M_StoreLoad)
+#define	LoadStore	MMASK_GEN(M_LoadStore)
+#define	StoreStore	MMASK_GEN(M_StoreStore)
+
+#define	casa(rs1, rs2, rd, asi) ({					\
+	u_int __rd = (uint32_t)(rd);					\
+	__asm __volatile("casa [%2] %3, %4, %0"				\
+	    : "+r" (__rd), "=m" (*rs1)					\
+	    : "r" (rs1), "n" (asi), "r" (rs2), "m" (*rs1));		\
+	__rd;								\
+})
+
+#define	casxa(rs1, rs2, rd, asi) ({					\
+	u_long __rd = (uint64_t)(rd);					\
+	__asm __volatile("casxa [%2] %3, %4, %0"			\
+	    : "+r" (__rd), "=m" (*rs1)					\
+	    : "r" (rs1), "n" (asi), "r" (rs2), "m" (*rs1));		\
+	__rd;								\
+})
+
+#define	flush(va) do {							\
+	__asm __volatile("flush %0" : : "r" (va));			\
+} while (0)
+
+#define	flushw() do {							\
+	__asm __volatile("flushw" : :);					\
+} while (0)
+
+#define	mov(val, reg) do {						\
+	__asm __volatile("mov %0, %" __XSTRING(reg) : : "r" (val));	\
+} while (0)
+
+/* Generate ld*a/st*a functions for non-constant ASIs. */
+#define	LDNC_GEN(tp, o)							\
+	static __inline tp						\
+	o ## _nc(caddr_t va, int asi)					\
+	{								\
+		tp r;							\
+		__asm __volatile("wr %2, 0, %%asi;" #o " [%1] %%asi, %0"\
+		    : "=r" (r) : "r" (va), "r" (asi));			\
+		return (r);						\
+	}
+
+LDNC_GEN(u_char, lduba);
+LDNC_GEN(u_short, lduha);
+LDNC_GEN(u_int, lduwa);
+LDNC_GEN(u_long, ldxa);
+
+#define	LD_GENERIC(va, asi, op, type) ({				\
+	type __r;							\
+	__asm __volatile(#op " [%1] %2, %0"				\
+	    : "=r" (__r) : "r" (va), "n" (asi));			\
+	__r;								\
+})
+
+#define	lduba(va, asi)	LD_GENERIC(va, asi, lduba, u_char)
+#define	lduha(va, asi)	LD_GENERIC(va, asi, lduha, u_short)
+#define	lduwa(va, asi)	LD_GENERIC(va, asi, lduwa, u_int)
+#define	ldxa(va, asi)	LD_GENERIC(va, asi, ldxa, u_long)
+
+#define	STNC_GEN(tp, o)							\
+	static __inline void						\
+	o ## _nc(caddr_t va, int asi, tp val)				\
+	{								\
+		__asm __volatile("wr %2, 0, %%asi;" #o " %0, [%1] %%asi"\
+		    : : "r" (val), "r" (va), "r" (asi));		\
+	}
+
+STNC_GEN(u_char, stba);
+STNC_GEN(u_short, stha);
+STNC_GEN(u_int, stwa);
+STNC_GEN(u_long, stxa);
+
+#define	ST_GENERIC(va, asi, val, op)					\
+	__asm __volatile(#op " %0, [%1] %2"				\
+	    : : "r" (val), "r" (va), "n" (asi));			\
+
+#define	stba(va, asi, val)	ST_GENERIC(va, asi, val, stba)
+#define	stha(va, asi, val)	ST_GENERIC(va, asi, val, stha)
+#define	stwa(va, asi, val)	ST_GENERIC(va, asi, val, stwa)
+#define	stxa(va, asi, val)	ST_GENERIC(va, asi, val, stxa)
+
+/*
+ * Attempt to read from addr, val.  If a Data Access Error trap happens,
+ * they return -1 and the contents of val is undefined.  A return of 0
+ * means no trap happened, and the contents of val is valid.
+ */
+int fasword8(u_long asi, void *addr, uint8_t *val);
+int fasword16(u_long asi, void *addr, uint16_t *val);
+int fasword32(u_long asi, void *addr, uint32_t *val);
+
+#define	membar(mask) do {						\
+	__asm __volatile("membar %0" : : "n" (mask) : "memory");	\
+} while (0)
+
+#define	rd(name) ({							\
+	uint64_t __sr;							\
+	__asm __volatile("rd %%" #name ", %0" : "=r" (__sr) :);		\
+	__sr;								\
+})
+
+#define	wr(name, val, xorval) do {					\
+	__asm __volatile("wr %0, %1, %%" #name				\
+	    : : "r" (val), "rI" (xorval));				\
+} while (0)
+
+#define	rdpr(name) ({							\
+	uint64_t __pr;							\
+	__asm __volatile("rdpr %%" #name", %0" : "=r" (__pr) :);	\
+	__pr;								\
+})
+
+#define	wrpr(name, val, xorval) do {					\
+	__asm __volatile("wrpr %0, %1, %%" #name			\
+	    : : "r" (val), "rI" (xorval));				\
+} while (0)
+
+/*
+ * Trick GAS/GCC into compiling access to TICK/(S)TICK_COMPARE independently
+ * of the selected instruction set.
+ */
+#define	rdtickcmpr()			rd(asr23)
+#define	rdstick()			rd(asr24)
+#define	rdstickcmpr()			rd(asr25)
+#define	wrtickcmpr(val, xorval)		wr(asr23, (val), (xorval))
+#define	wrstick(val, xorval)		wr(asr24, (val), (xorval))
+#define	wrstickcmpr(val, xorval)	wr(asr25, (val), (xorval))
+
+/*
+ * Macro intended to be used instead of wr(asr23, val, xorval) for writing to
+ * the TICK_COMPARE register in order to avoid a bug in BlackBird CPUs that
+ * can cause these writes to fail under certain conditions which in turn
+ * causes the hardclock to stop.  The workaround is to read the TICK_COMPARE
+ * register back immediately after writing to it with these two instructions
+ * aligned to a quadword boundary in order to ensure that I$ misses won't
+ * split them up.
+ */
+#define	wrtickcmpr_bbwar(val, xorval) ({				\
+	__asm __volatile(						\
+	"	ba,pt	%%xcc, 1f ;		"			\
+	"	 nop	 ;			"			\
+	"	.align	128 ;			"			\
+	"1:	wr	%0, %1, %%asr23 ;	"			\
+	"	rd	%%asr23, %%g0 ;		"			\
+	: : "r" (val), "rI" (xorval));					\
+})
+
+static __inline void
+breakpoint(void)
+{
+
+	__asm __volatile("ta %%xcc, 1" : :);
+}
+
+static __inline register_t
+intr_disable(void)
+{
+	register_t s;
+
+	s = rdpr(pstate);
+	wrpr(pstate, s & ~PSTATE_IE, 0);
+	return (s);
+}
+#define	intr_restore(s)	wrpr(pstate, (s), 0)
+
+/*
+ * In some places, it is required that the store is directly followed by a
+ * membar #Sync.  Don't trust the compiler to not insert instructions in
+ * between.  We also need to disable interrupts completely.
+ */
+#define	stxa_sync(va, asi, val) do {					\
+	register_t s;							\
+	s = intr_disable();						\
+	__asm __volatile("stxa %0, [%1] %2; membar #Sync"		\
+	    : : "r" (val), "r" (va), "n" (asi));			\
+	intr_restore(s);						\
+} while (0)
+
+void ascopy(u_long asi, vm_offset_t src, vm_offset_t dst, size_t len);
+void ascopyfrom(u_long sasi, vm_offset_t src, caddr_t dst, size_t len);
+void ascopyto(caddr_t src, u_long dasi, vm_offset_t dst, size_t len);
+void aszero(u_long asi, vm_offset_t dst, size_t len);
+
+/*
+ * Ultrasparc II doesn't implement popc in hardware.
+ */
+#if 0
+#define	HAVE_INLINE_FFS
+/*
+ * See page 202 of the SPARC v9 Architecture Manual.
+ */
+static __inline int
+ffs(int mask)
+{
+	int result;
+	int neg;
+	int tmp;
+
+	__asm __volatile(
+	"	neg	%3, %1 ;	"
+	"	xnor	%3, %1, %2 ;	"
+	"	popc	%2, %0 ;	"
+	"	movrz	%3, %%g0, %0 ;	"
+	: "=r" (result), "=r" (neg), "=r" (tmp) : "r" (mask));
+	return (result);
+}
+#endif
+
+#undef LDNC_GEN
+#undef STNC_GEN
+
+#endif /* !_MACHINE_CPUFUNC_H_ */


Property changes on: trunk/sys/sparc64/include/cpufunc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/db_machdep.h
===================================================================
--- trunk/sys/sparc64/include/db_machdep.h	                        (rev 0)
+++ trunk/sys/sparc64/include/db_machdep.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,70 @@
+/* $MidnightBSD$ */
+/*-
+ * Mach Operating System
+ * Copyright (c) 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 "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 at 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.
+ *
+ *	from: FreeBSD: src/sys/i386/include/db_machdep.h,v 1.16 1999/10/04
+ * $FreeBSD: stable/10/sys/sparc64/include/db_machdep.h 139825 2005-01-07 02:29:27Z imp $
+ */
+
+#ifndef	_MACHINE_DB_MACHDEP_H_
+#define	_MACHINE_DB_MACHDEP_H_
+
+#include <machine/frame.h>
+#include <machine/trap.h>
+
+#define	BYTE_MSF	(1)
+
+typedef vm_offset_t	db_addr_t;
+typedef long		db_expr_t;
+
+#define	PC_REGS()	((db_addr_t)kdb_thrctx->pcb_pc)
+
+#define	BKPT_INST	(0x91d03001)
+#define	BKPT_SIZE	(4)
+#define	BKPT_SET(inst)	(BKPT_INST)
+
+#define	BKPT_SKIP do {							\
+	kdb_frame->tf_tpc = kdb_frame->tf_tnpc + 4;			\
+	kdb_frame->tf_tnpc += 8;					\
+} while (0)
+
+#define	db_clear_single_step	kdb_cpu_clear_singlestep
+#define	db_set_single_step	kdb_cpu_set_singlestep
+
+#define	IS_BREAKPOINT_TRAP(type, code)	(type == T_BREAKPOINT)
+#define	IS_WATCHPOINT_TRAP(type, code)	(0)
+
+#define	inst_trap_return(ins)	(0)
+#define	inst_return(ins)	(0)
+#define	inst_call(ins)		(0)
+#define	inst_load(ins)		(0)
+#define	inst_store(ins)		(0)
+
+#define	DB_SMALL_VALUE_MAX	(0x7fffffff)
+#define	DB_SMALL_VALUE_MIN	(-0x40001)
+
+#define	DB_ELFSIZE		64
+
+#endif /* !_MACHINE_DB_MACHDEP_H_ */


Property changes on: trunk/sys/sparc64/include/db_machdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/dcr.h
===================================================================
--- trunk/sys/sparc64/include/dcr.h	                        (rev 0)
+++ trunk/sys/sparc64/include/dcr.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,71 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Marius Strobl <marius at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/dcr.h 206450 2010-04-10 11:13:51Z marius $
+ */
+
+#ifndef	_MACHINE_DCR_H_
+#define	_MACHINE_DCR_H_
+
+/*
+ * Definitions for the UltraSPARC-III Depatch Control Register (ASR 18).
+ */
+#define	DCR_MS			(1UL << 0)
+#define	DCR_IFPOE		(1UL << 1)
+#define	DCR_SI			(1UL << 3)
+#define	DCR_RPE			(1UL << 4)
+#define	DCR_BPE			(1UL << 5)
+
+#define	DCR_OBSDATA_SHIFT	6
+#define	DCR_OBSDATA_CT_BITS	8
+#define	DCR_OBSDATA_CT_MASK						\
+	(((1UL << DCR_OBSDATA_CT_BITS) - 1) << DCR_OBSDATA_SHIFT)
+
+/* The following bits are valid for the UltraSPARC-III++/IV+ only. */
+#define	DCR_IPE			(1UL << 2)
+
+#define	DCR_OBSDATA_CTP_BITS	6
+#define	DCR_OBSDATA_CTP_MASK						\
+	(((1UL << DCR_OBSDATA_CTP_BITS) - 1) << DCR_OBSDATA_SHIFT)
+
+#define	DCR_DPE			(1UL << 12)
+
+/* The following bits are valid for the UltraSPARC-IV+ only. */
+#define	DCR_BPM_SHIFT		13
+#define	DCR_BPM_BITS		2
+#define	DCR_BPM_MASK							\
+	(((1UL << DCR_BPM_BITS) - 1) << DCR_BPM_SHIFT)
+#define	DCR_BPM_1HIST_GSHARE	(0UL << DCR_BPM_SHIFT)
+#define	DCR_BPM_2HIST_GSHARE	(1UL << DCR_BPM_SHIFT)
+#define	DCR_BPM_PC		(2UL << DCR_BPM_SHIFT)
+#define	DCR_BPM_2HIST_MIXED	(3UL << DCR_BPM_SHIFT)
+
+#define	DCR_JPE			(1UL << 15)
+#define	DCR_ITPE		(1UL << 16)
+#define	DCR_DTPE		(1UL << 17)
+#define	DCR_PPE			(1UL << 18)
+
+#endif	/* _MACHINE_DCR_H_ */


Property changes on: trunk/sys/sparc64/include/dcr.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/elf.h
===================================================================
--- trunk/sys/sparc64/include/elf.h	                        (rev 0)
+++ trunk/sys/sparc64/include/elf.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,111 @@
+/* $MidnightBSD$ */
+/*-
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/elf.h 237430 2012-06-22 06:38:31Z kib $
+ */
+
+#ifndef	_MACHINE_ELF_H_
+#define	_MACHINE_ELF_H_ 1
+
+/*
+ * ELF definitions for the sparc64 architecture.
+ */
+
+#include <sys/elf32.h>	/* Definitions common to all 32 bit architectures. */
+#include <sys/elf64.h>	/* Definitions common to all 64 bit architectures. */
+
+#ifndef __ELF_WORD_SIZE
+#define	__ELF_WORD_SIZE	64	/* Used by <sys/elf_generic.h> */
+#endif
+#include <sys/elf_generic.h>
+
+#define	ELF_ARCH	EM_SPARCV9
+
+#define	ELF_MACHINE_OK(x)	((x) == ELF_ARCH)
+
+/*
+ * Auxiliary vector entries for passing information to the interpreter.
+ */
+
+typedef struct {	/* Auxiliary vector entry on initial stack */
+	int	a_type;			/* Entry type. */
+	union {
+		int	a_val;		/* Integer value. */
+	} a_un;
+} Elf32_Auxinfo;
+
+typedef struct {	/* Auxiliary vector entry on initial stack */
+	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;
+} Elf64_Auxinfo;
+
+__ElfType(Auxinfo);
+
+/* Values for a_type. */
+#define	AT_NULL		0	/* Terminates the vector. */
+#define	AT_IGNORE	1	/* Ignored entry. */
+#define	AT_EXECFD	2	/* File descriptor of program to load. */
+#define	AT_PHDR		3	/* Program header of program already loaded. */
+#define	AT_PHENT	4	/* Size of each program header entry. */
+#define	AT_PHNUM	5	/* Number of program header entries. */
+#define	AT_PAGESZ	6	/* Page size in bytes. */
+#define	AT_BASE		7	/* Interpreter's base address. */
+#define	AT_FLAGS	8	/* Flags (unused). */
+#define	AT_ENTRY	9	/* Where interpreter should transfer control. */
+#define	AT_NOTELF	10	/* Program is not ELF ?? */
+#define	AT_UID		11	/* Real uid. */
+#define	AT_EUID		12	/* Effective uid. */
+#define	AT_GID		13	/* Real gid. */
+#define	AT_EGID		14	/* Effective gid. */
+#define	AT_EXECPATH	15	/* Path to the executable. */
+#define	AT_CANARY	16	/* Canary for SSP */
+#define	AT_CANARYLEN	17	/* Length of the canary. */
+#define	AT_OSRELDATE	18	/* OSRELDATE. */
+#define	AT_NCPUS	19	/* Number of CPUs. */
+#define	AT_PAGESIZES	20	/* Pagesizes. */
+#define	AT_PAGESIZESLEN	21	/* Number of pagesizes. */
+#define	AT_TIMEKEEP	22	/* Pointer to timehands. */
+#define	AT_STACKPROT	23	/* Initial stack protection. */
+
+#define	AT_COUNT	24	/* Count of defined aux entry types. */
+
+/* Define "machine" characteristics */
+#if __ELF_WORD_SIZE == 32
+#define	ELF_TARG_CLASS  ELFCLASS32
+#else
+#define	ELF_TARG_CLASS  ELFCLASS64
+#endif
+#define	ELF_TARG_DATA	ELFDATA2MSB
+#define	ELF_TARG_MACH	ELF_ARCH
+#define	ELF_TARG_VER	1
+
+#define	ET_DYN_LOAD_ADDR 0x100000
+
+#endif /* !_MACHINE_ELF_H_ */


Property changes on: trunk/sys/sparc64/include/elf.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/endian.h
===================================================================
--- trunk/sys/sparc64/include/endian.h	                        (rev 0)
+++ trunk/sys/sparc64/include/endian.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,125 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1987, 1991, 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.
+ * 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.
+ *
+ *	@(#)endian.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: stable/10/sys/sparc64/include/endian.h 232745 2012-03-09 20:34:31Z dim $
+ */
+
+#ifndef _MACHINE_ENDIAN_H_
+#define	_MACHINE_ENDIAN_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+/*
+ * Define the order of 32-bit words in 64-bit words.
+ */
+#define	_QUAD_HIGHWORD 0
+#define	_QUAD_LOWWORD 1
+
+/*
+ * Definitions for byte order, according to byte significance from low
+ * address to high.
+ */
+#define	_LITTLE_ENDIAN	1234	/* LSB first: i386, vax */
+#define	_BIG_ENDIAN	4321	/* MSB first: 68000, ibm, net */
+#define	_PDP_ENDIAN	3412	/* LSB first in word, MSW first in long */
+
+#define	_BYTE_ORDER	_BIG_ENDIAN
+
+/*
+ * Deprecated variants that don't have enough underscores to be useful in more
+ * strict namespaces.
+ */
+#if __BSD_VISIBLE
+#define	LITTLE_ENDIAN	_LITTLE_ENDIAN
+#define	BIG_ENDIAN	_BIG_ENDIAN
+#define	PDP_ENDIAN	_PDP_ENDIAN
+#define	BYTE_ORDER	_BYTE_ORDER
+#endif
+
+#if defined(__GNUCLIKE_BUILTIN_CONSTANT_P) && defined(__OPTIMIZE__)
+#define	__is_constant(x)	__builtin_constant_p(x)
+#else
+#define	__is_constant(x)	0
+#endif
+
+#define	__bswap16_const(x)	((((__uint16_t)(x) >> 8) & 0xff) |	\
+	(((__uint16_t)(x) << 8) & 0xff00))
+#define	__bswap32_const(x)	((((__uint32_t)(x) >> 24) & 0xff) |	\
+	(((__uint32_t)(x) >> 8) & 0xff00) |				\
+	(((__uint32_t)(x)<< 8) & 0xff0000) |				\
+	(((__uint32_t)(x) << 24) & 0xff000000))
+#define	__bswap64_const(x)	((((__uint64_t)(x) >> 56) & 0xff) |	\
+	(((__uint64_t)(x) >> 40) & 0xff00) |				\
+	(((__uint64_t)(x) >> 24) & 0xff0000) |				\
+	(((__uint64_t)(x) >> 8) & 0xff000000) |				\
+	(((__uint64_t)(x) << 8) & ((__uint64_t)0xff << 32)) |		\
+	(((__uint64_t)(x) << 24) & ((__uint64_t)0xff << 40)) |		\
+	(((__uint64_t)(x) << 40) & ((__uint64_t)0xff << 48)) |		\
+	(((__uint64_t)(x) << 56) & ((__uint64_t)0xff << 56)))
+
+static __inline __uint16_t
+__bswap16_var(__uint16_t _x)
+{
+
+	return ((_x >> 8) | ((_x << 8) & 0xff00));
+}
+
+static __inline __uint32_t
+__bswap32_var(__uint32_t _x)
+{
+
+	return ((_x >> 24) | ((_x >> 8) & 0xff00) | ((_x << 8) & 0xff0000) |
+	    ((_x << 24) & 0xff000000));
+}
+
+static __inline __uint64_t
+__bswap64_var(__uint64_t _x)
+{
+
+	return ((_x >> 56) | ((_x >> 40) & 0xff00) | ((_x >> 24) & 0xff0000) |
+	    ((_x >> 8) & 0xff000000) | ((_x << 8) & ((__uint64_t)0xff << 32)) |
+	    ((_x << 24) & ((__uint64_t)0xff << 40)) |
+	    ((_x << 40) & ((__uint64_t)0xff << 48)) | ((_x << 56)));
+}
+
+#define	__bswap16(x)	((__uint16_t)(__is_constant(x) ? __bswap16_const(x) : \
+	__bswap16_var(x)))
+#define	__bswap32(x)	(__is_constant(x) ? __bswap32_const(x) : \
+	__bswap32_var(x))
+#define	__bswap64(x)	(__is_constant(x) ? __bswap64_const(x) : \
+	__bswap64_var(x))
+
+#define	__htonl(x)	((__uint32_t)(x))
+#define	__htons(x)	((__uint16_t)(x))
+#define	__ntohl(x)	((__uint32_t)(x))
+#define	__ntohs(x)	((__uint16_t)(x))
+
+#endif /* !_MACHINE_ENDIAN_H_ */


Property changes on: trunk/sys/sparc64/include/endian.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/exec.h
===================================================================
--- trunk/sys/sparc64/include/exec.h	                        (rev 0)
+++ trunk/sys/sparc64/include/exec.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,35 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/exec.h 81334 2001-08-09 02:09:34Z obrien $
+ */
+
+#ifndef	_MACHINE_EXEC_H_
+#define	_MACHINE_EXEC_H_
+
+#define	__LDPGSZ	8192
+
+#endif /* !_MACHINE_EXEC_H_ */


Property changes on: trunk/sys/sparc64/include/exec.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/fireplane.h
===================================================================
--- trunk/sys/sparc64/include/fireplane.h	                        (rev 0)
+++ trunk/sys/sparc64/include/fireplane.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,41 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Marius Strobl <marius at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/fireplane.h 203829 2010-02-13 14:13:39Z marius $
+ */
+
+#ifndef _MACHINE_FIREPLANE_H_
+#define	_MACHINE_FIREPLANE_H_
+
+#define	FIREPLANE_CR_AID_SHIFT	(17)
+#define	FIREPLANE_CR_AID_SIZE	(10)
+#define	FIREPLANE_CR_AID_MASK						\
+	(((1 << FIREPLANE_CR_AID_SIZE) - 1) << FIREPLANE_CR_AID_SHIFT)
+
+#define	FIREPLANE_CR_GET_AID(cr)					\
+	((cr & FIREPLANE_CR_AID_MASK) >> FIREPLANE_CR_AID_SHIFT)
+
+#endif /* _MACHINE_FIREPLANE_H_ */


Property changes on: trunk/sys/sparc64/include/fireplane.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/float.h
===================================================================
--- trunk/sys/sparc64/include/float.h	                        (rev 0)
+++ trunk/sys/sparc64/include/float.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,100 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1992, 1993, 2001
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 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.
+ *
+ *	@(#)float.h	8.1 (Berkeley) 6/11/93
+ *	from: NetBSD: float.h,v 1.3 2001/09/21 20:48:02 eeh Exp
+ * $FreeBSD: stable/10/sys/sparc64/include/float.h 230475 2012-01-23 06:36:41Z das $
+ */
+
+#ifndef _MACHINE_FLOAT_H_
+#define _MACHINE_FLOAT_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int __flt_rounds(void);
+__END_DECLS
+
+#define FLT_RADIX	2		/* b */
+#define FLT_ROUNDS	__flt_rounds()
+#if __ISO_C_VISIBLE >= 1999
+#define	FLT_EVAL_METHOD	0		/* no promotion */
+#define	DECIMAL_DIG	36		/* max precision in decimal digits */
+#endif
+
+#define FLT_MANT_DIG	24		/* p */
+#define FLT_EPSILON	1.19209290E-7F	/* b**(1-p) */
+#define FLT_DIG		6		/* floor((p-1)*log10(b))+(b == 10) */
+#define FLT_MIN_EXP	(-125)		/* emin */
+#define FLT_MIN		1.17549435E-38F	/* b**(emin-1) */
+#define FLT_MIN_10_EXP	(-37)		/* ceil(log10(b**(emin-1))) */
+#define FLT_MAX_EXP	128		/* emax */
+#define FLT_MAX		3.40282347E+38F	/* (1-b**(-p))*b**emax */
+#define FLT_MAX_10_EXP	38		/* floor(log10((1-b**(-p))*b**emax)) */
+#if __ISO_C_VISIBLE >= 2011
+#define	FLT_TRUE_MIN	1.40129846E-45F	/* b**(emin-p) */
+#define	FLT_DECIMAL_DIG	9		/* ceil(1+p*log10(b)) */
+#define	FLT_HAS_SUBNORM	1
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#define DBL_MANT_DIG	53
+#define DBL_EPSILON	2.2204460492503131E-16
+#define DBL_DIG		15
+#define DBL_MIN_EXP	(-1021)
+#define DBL_MIN		2.2250738585072014E-308
+#define DBL_MIN_10_EXP	(-307)
+#define DBL_MAX_EXP	1024
+#define DBL_MAX		1.7976931348623157E+308
+#define DBL_MAX_10_EXP	308
+#if __ISO_C_VISIBLE >= 2011
+#define	DBL_TRUE_MIN	4.9406564584124654E-324
+#define	DBL_DECIMAL_DIG	17
+#define	DBL_HAS_SUBNORM	1
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#define LDBL_MANT_DIG	113
+#define LDBL_EPSILON	1.925929944387235853055977942584927319E-34L
+#define LDBL_DIG	33
+#define LDBL_MIN_EXP	(-16381)
+#define LDBL_MIN	3.362103143112093506262677817321752603E-4932L
+#define LDBL_MIN_10_EXP	(-4931)
+#define LDBL_MAX_EXP	(+16384)
+#define LDBL_MAX	1.189731495357231765085759326628007016E+4932L
+#define LDBL_MAX_10_EXP	(+4932)
+#if __ISO_C_VISIBLE >= 2011
+#define	LDBL_TRUE_MIN	6.475175119438025110924438958227646552E-4966L
+#define	LDBL_DECIMAL_DIG 36
+#define	LDBL_HAS_SUBNORM 1
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#endif	/* _MACHINE_FLOAT_H_ */


Property changes on: trunk/sys/sparc64/include/float.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/floatingpoint.h
===================================================================
--- trunk/sys/sparc64/include/floatingpoint.h	                        (rev 0)
+++ trunk/sys/sparc64/include/floatingpoint.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,38 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 David O'Brien <obrien at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DAVID O'BRIEN 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/floatingpoint.h 139825 2005-01-07 02:29:27Z imp $
+ */
+
+#ifndef _FLOATINGPOINT_H_
+#define _FLOATINGPOINT_H_
+
+#include <machine/ieeefp.h>
+
+#endif /* !_FLOATINGPOINT_H_ */


Property changes on: trunk/sys/sparc64/include/floatingpoint.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/fp.h
===================================================================
--- trunk/sys/sparc64/include/fp.h	                        (rev 0)
+++ trunk/sys/sparc64/include/fp.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,40 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2001 by Thomas Moestl <tmm at 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, 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 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/fp.h 112920 2003-04-01 04:02:45Z jake $
+ */
+
+#ifndef	_MACHINE_FP_H_
+#define	_MACHINE_FP_H_
+
+#ifdef _KERNEL
+
+/*
+ * Note: The pointer passed to savefpctx must be aligned on a 64 byte
+ * boundary.
+ */
+void	savefpctx(uint32_t *fp);
+
+#endif /* _KERNEL */
+#endif /* !_MACHINE_FP_H_ */


Property changes on: trunk/sys/sparc64/include/fp.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/frame.h
===================================================================
--- trunk/sys/sparc64/include/frame.h	                        (rev 0)
+++ trunk/sys/sparc64/include/frame.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,94 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/frame.h 166105 2007-01-19 11:15:34Z marius $
+ */
+
+#ifndef	_MACHINE_FRAME_H_
+#define	_MACHINE_FRAME_H_
+
+#define	RW_SHIFT	7
+#define	SPOFF		2047
+#define	BIAS		SPOFF		/* XXX - open/netbsd compat */
+
+#ifndef LOCORE
+
+/*
+ * NOTE: keep this structure in sync with struct reg and struct mcontext.
+ */
+struct trapframe {
+	uint64_t tf_global[8];
+	uint64_t tf_out[8];
+	uint64_t tf_fprs;
+	uint64_t tf_fsr;
+	uint64_t tf_gsr;
+	uint64_t tf_level;
+	uint64_t tf_pil;
+	uint64_t tf_sfar;
+	uint64_t tf_sfsr;
+	uint64_t tf_tar;
+	uint64_t tf_tnpc;
+	uint64_t tf_tpc;
+	uint64_t tf_tstate;
+	uint64_t tf_type;
+	uint64_t tf_y;
+	uint64_t tf_wstate;
+	uint64_t tf_pad[2];
+};
+#define	tf_sp	tf_out[6]
+
+#define	TF_DONE(tf) do { \
+	tf->tf_tpc = tf->tf_tnpc; \
+	tf->tf_tnpc += 4; \
+} while (0)
+
+struct frame {
+	u_long	fr_local[8];
+	u_long	fr_in[8];
+	u_long	fr_pad[8];
+};
+#define	fr_arg	fr_in
+#define	fr_fp	fr_in[6]
+#define	fr_pc	fr_in[7]
+
+#define	v9next_frame(fp)	((struct frame *)(fp->fr_fp + BIAS))
+
+/*
+ * Frame used for pcb_rw.
+ */
+struct rwindow {
+	u_long	rw_local[8];
+	u_long	rw_in[8];
+};
+
+struct thread;
+
+int	rwindow_save(struct thread *td);
+int	rwindow_load(struct thread *td, struct trapframe *tf, int n);
+
+#endif /* !LOCORE */
+
+#endif /* !_MACHINE_FRAME_H_ */


Property changes on: trunk/sys/sparc64/include/frame.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/fsr.h
===================================================================
--- trunk/sys/sparc64/include/fsr.h	                        (rev 0)
+++ trunk/sys/sparc64/include/fsr.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,115 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2001 by Thomas Moestl <tmm at 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, 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 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/fsr.h 239941 2012-08-31 11:15:01Z marius $
+ */
+
+#ifndef	_MACHINE_FSR_H_
+#define	_MACHINE_FSR_H_
+
+#define	FPRS_DL		(1 << 0)
+#define	FPRS_DU		(1 << 1)
+#define	FPRS_FEF	(1 << 2)
+
+#define	VIS_BLOCKSIZE	64
+
+#ifndef LOCORE
+
+#define	FSR_EXC_BITS	5
+#define	FSR_EXC_MASK	((1UL << FSR_EXC_BITS) - 1)
+#define	FSR_CEXC_SHIFT	0
+#define	FSR_CEXC_MASK	(FSR_EXC_MASK << FSR_CEXC_SHIFT)
+#define	FSR_CEXC(b)	((unsigned long)(b) << FSR_CEXC_SHIFT)
+#define	FSR_GET_CEXC(x)	(((x) & FSR_CEXC_MASK) >> FSR_CEXC_SHIFT)
+#define	FSR_AEXC_SHIFT	5
+#define	FSR_AEXC_MASK	(FSR_EXC_MASK << FSR_AEXC_SHIFT)
+#define	FSR_AEXC(b)	((unsigned long)(b) << FSR_AEXC_SHIFT)
+#define	FSR_GET_AEXC(x)	(((x) & FSR_AEXC_MASK) >> FSR_AEXC_SHIFT)
+#define	FSR_QNE		(1UL << 13)
+#define	FSR_NS		(1UL << 22)
+#define	FSR_TEM_SHIFT	23
+#define	FSR_TEM_MASK	(FSR_EXC_MASK << FSR_TEM_SHIFT)
+#define	FSR_TEM(b)	((unsigned long)(b) << FSR_TEM_SHIFT)
+#define	FSR_GET_TEM(x)	(((x) & FSR_TEM_MASK) >> FSR_TEM_SHIFT)
+#define	FSR_FCC0_SHIFT	10
+#define	FSR_FCC0_BITS	2
+#define	FSR_FCC0_MASK	(((1UL << FSR_FCC0_BITS) - 1) << FSR_FCC0_SHIFT)
+#define	FSR_FCC0(x)	((unsigned long)(x) << FSR_FCC0_SHIFT)
+#define	FSR_GET_FCC0(x)	(((x) & FSR_FCC0_MASK) >> FSR_FCC0_SHIFT)
+#define	FSR_FTT_SHIFT	14
+#define	FSR_FTT_BITS	3
+#define	FSR_FTT_MASK	(((1UL << FSR_FTT_BITS) - 1) << FSR_FTT_SHIFT)
+#define	FSR_FTT(x)	((unsigned long)(x) << FSR_FTT_SHIFT)
+#define	FSR_GET_FTT(x)	(((x) & FSR_FTT_MASK) >> FSR_FTT_SHIFT)
+#define	FSR_VER_SHIFT	17
+#define	FSR_GET_VER(x)	(((x) >> FSR_VER_SHIFT) & 7)
+#define	FSR_RD_SHIFT	30
+#define	FSR_RD_BITS	2
+#define	FSR_RD_MASK	(((1UL << FSR_RD_BITS) - 1) << FSR_RD_SHIFT)
+#define	FSR_RD(x)	((unsigned long)(x) << FSR_RD_SHIFT)
+#define	FSR_GET_RD(x)	(((x) & FSR_RD_MASK) >> FSR_RD_SHIFT)
+#define	FSR_FCC1_SHIFT	32
+#define	FSR_FCC1_BITS	2
+#define	FSR_FCC1_MASK	(((1UL << FSR_FCC1_BITS) - 1) << FSR_FCC1_SHIFT)
+#define	FSR_FCC1(x)	((unsigned long)(x) << FSR_FCC1_SHIFT)
+#define	FSR_GET_FCC1(x)	(((x) & FSR_FCC1_MASK) >> FSR_FCC1_SHIFT)
+#define	FSR_FCC2_SHIFT	34
+#define	FSR_FCC2_BITS	2
+#define	FSR_FCC2_MASK	(((1UL << FSR_FCC2_BITS) - 1) << FSR_FCC2_SHIFT)
+#define	FSR_FCC2(x)	((unsigned long)(x) << FSR_FCC2_SHIFT)
+#define	FSR_GET_FCC2(x)	(((x) & FSR_FCC2_MASK) >> FSR_FCC2_SHIFT)
+#define	FSR_FCC3_SHIFT	36
+#define	FSR_FCC3_BITS	2
+#define	FSR_FCC3_MASK	(((1UL << FSR_FCC3_BITS) - 1) << FSR_FCC3_SHIFT)
+#define	FSR_FCC3(x)	((unsigned long)(x) << FSR_FCC3_SHIFT)
+#define	FSR_GET_FCC3(x)	(((x) & FSR_FCC3_MASK) >> FSR_FCC3_SHIFT)
+
+/* CEXC/AEXC/TEM exception values */
+#define	FSR_NX		(1 << 0)
+#define	FSR_DZ		(1 << 1)
+#define	FSR_UF		(1 << 2)
+#define	FSR_OF		(1 << 3)
+#define	FSR_NV		(1 << 4)
+/* FTT values. */
+#define	FSR_FTT_NONE	0
+#define	FSR_FTT_IEEE	1
+#define	FSR_FTT_UNFIN	2
+#define	FSR_FTT_UNIMP	3
+#define	FSR_FTT_SEQERR	4
+#define	FSR_FTT_HWERR	5
+#define	FSR_FTT_INVREG	6
+/* RD values */
+#define	FSR_RD_N	0		/* nearest */
+#define	FSR_RD_Z	1		/* zero */
+#define	FSR_RD_PINF	2		/* +infinity */
+#define	FSR_RD_NINF	3		/* -infinity */
+/* condition codes */
+#define	FSR_CC_EQ	0	/* a = b */
+#define	FSR_CC_LT	1	/* a < b */
+#define	FSR_CC_GT	2	/* a > b */
+#define	FSR_CC_UO	3	/* unordered */
+
+#endif /* !LOCORE */
+
+#endif /* !_MACHINE_FSR_H_ */


Property changes on: trunk/sys/sparc64/include/fsr.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/gdb_machdep.h
===================================================================
--- trunk/sys/sparc64/include/gdb_machdep.h	                        (rev 0)
+++ trunk/sys/sparc64/include/gdb_machdep.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,58 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Marcel Moolenaar
+ * 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 ``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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/gdb_machdep.h 139825 2005-01-07 02:29:27Z imp $
+ */
+
+#ifndef _MACHINE_GDB_MACHDEP_H_
+#define	_MACHINE_GDB_MACHDEP_H_
+
+#define	GDB_BUFSZ	600
+#define	GDB_NREGS	86
+#define	GDB_REG_PC	80
+
+static __inline size_t
+gdb_cpu_regsz(int regnum)
+{
+	return ((regnum >= 32 && regnum < 64) ? sizeof(float) : sizeof(long));
+}
+
+static __inline int
+gdb_cpu_query(void)
+{
+	return (0);
+}
+
+static __inline int
+gdb_cpu_signal(int vector, int _)
+{
+	return (vector);
+}
+
+void *gdb_cpu_getreg(int, size_t *);
+void gdb_cpu_setreg(int, void *);
+
+#endif /* !_MACHINE_GDB_MACHDEP_H_ */


Property changes on: trunk/sys/sparc64/include/gdb_machdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/idprom.h
===================================================================
--- trunk/sys/sparc64/include/idprom.h	                        (rev 0)
+++ trunk/sys/sparc64/include/idprom.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,64 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1993 Adam Glass
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Adam Glass.
+ * 4. The name of the Author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: idprom.h,v 1.2 1998/09/05 23:57:26 eeh Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/idprom.h 139825 2005-01-07 02:29:27Z imp $
+ */
+
+#ifndef _MACHINE_IDPROM_H_
+#define _MACHINE_IDPROM_H_
+
+/*
+ * ID prom format.  The ``host id'' is set up by taking the machine
+ * ID as the top byte and the hostid field as the remaining three.
+ * The id_xxx0 field appears to contain some other number.  The id_xxx1
+ * contains a bunch of 00's and a5's on my machines, suggesting it is
+ * not actually used.  The checksum seems to include them, however.
+ */
+struct idprom {
+	u_char	id_format;		/* format identifier (= 1) */
+	u_char	id_machine;		/* machine type (see param.h) */
+	u_char	id_ether[6];		/* ethernet address */
+	int	id_date;		/* date of manufacture */
+	u_char	id_hostid[3];		/* ``host id'' bytes */
+	u_char	id_checksum;		/* xor of everything else */
+	char	id_undef[16];		/* undefined */
+};
+
+#define ID_SUN4_100	0x22
+#define ID_SUN4_200	0x21
+#define ID_SUN4_300	0x23
+#define ID_SUN4_400	0x24
+
+#define IDPROM_VERSION 1
+
+#endif /* !_MACHINE_IDPROM_H_ */


Property changes on: trunk/sys/sparc64/include/idprom.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/ieee.h
===================================================================
--- trunk/sys/sparc64/include/ieee.h	                        (rev 0)
+++ trunk/sys/sparc64/include/ieee.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,138 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 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.
+ *
+ *	@(#)ieee.h	8.1 (Berkeley) 6/11/93
+ *	from: NetBSD: ieee.h,v 1.1.1.1 1998/06/20 04:58:51 eeh Exp
+ * $FreeBSD: stable/10/sys/sparc64/include/ieee.h 139825 2005-01-07 02:29:27Z imp $
+ */
+
+#ifndef _MACHINE_IEEE_H_
+#define	_MACHINE_IEEE_H_
+
+/*
+ * ieee.h defines the machine-dependent layout of the machine's IEEE
+ * floating point.  It does *not* define (yet?) any of the rounding
+ * mode bits, exceptions, and so forth.
+ */
+
+/*
+ * Define the number of bits in each fraction and exponent.
+ *
+ *		     k	         k+1
+ * Note that  1.0 x 2  == 0.1 x 2      and that denorms are represented
+ *
+ *					  (-exp_bias+1)
+ * as fractions that look like 0.fffff x 2             .  This means that
+ *
+ *			 -126
+ * the number 0.10000 x 2    , for instance, is the same as the normalized
+ *
+ *		-127			   -128
+ * float 1.0 x 2    .  Thus, to represent 2    , we need one leading zero
+ *
+ *				  -129
+ * in the fraction; to represent 2    , we need two, and so on.  This
+ *
+ *						     (-exp_bias-fracbits+1)
+ * implies that the smallest denormalized number is 2
+ *
+ * for whichever format we are talking about: for single precision, for
+ *
+ *						-126		-149
+ * instance, we get .00000000000000000000001 x 2    , or 1.0 x 2    , and
+ *
+ * -149 == -127 - 23 + 1.
+ */
+#define	SNG_EXPBITS	8
+#define	SNG_FRACBITS	23
+
+#define	DBL_EXPBITS	11
+#define	DBL_FRACBITS	52
+
+#ifdef notyet
+#define	E80_EXPBITS	15
+#define	E80_FRACBITS	64
+#endif
+
+#define	EXT_EXPBITS	15
+#define	EXT_FRACBITS	112
+
+struct ieee_single {
+	u_int	sng_sign:1;
+	u_int	sng_exp:8;
+	u_int	sng_frac:23;
+};
+
+struct ieee_double {
+	u_int	dbl_sign:1;
+	u_int	dbl_exp:11;
+	u_int	dbl_frach:20;
+	u_int	dbl_fracl;
+};
+
+struct ieee_ext {
+	u_int	ext_sign:1;
+	u_int	ext_exp:15;
+	u_int	ext_frach:16;
+	u_int	ext_frachm;
+	u_int	ext_fraclm;
+	u_int	ext_fracl;
+};
+
+/*
+ * Floats whose exponent is in [1..INFNAN) (of whatever type) are
+ * `normal'.  Floats whose exponent is INFNAN are either Inf or NaN.
+ * Floats whose exponent is zero are either zero (iff all fraction
+ * bits are zero) or subnormal values.
+ *
+ * A NaN is a `signalling NaN' if its QUIETNAN bit is clear in its
+ * high fraction; if the bit is set, it is a `quiet NaN'.
+ */
+#define	SNG_EXP_INFNAN	255
+#define	DBL_EXP_INFNAN	2047
+#define	EXT_EXP_INFNAN	32767
+
+#if 0
+#define	SNG_QUIETNAN	(1 << 22)
+#define	DBL_QUIETNAN	(1 << 19)
+#define	EXT_QUIETNAN	(1 << 15)
+#endif
+
+/*
+ * Exponent biases.
+ */
+#define	SNG_EXP_BIAS	127
+#define	DBL_EXP_BIAS	1023
+#define	EXT_EXP_BIAS	16383
+
+#endif


Property changes on: trunk/sys/sparc64/include/ieee.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/ieeefp.h
===================================================================
--- trunk/sys/sparc64/include/ieeefp.h	                        (rev 0)
+++ trunk/sys/sparc64/include/ieeefp.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,38 @@
+/* $MidnightBSD$ */
+/*-
+ * Written by J.T. Conklin, Apr 6, 1995
+ * Public domain.
+ * $FreeBSD: stable/10/sys/sparc64/include/ieeefp.h 226607 2011-10-21 06:41:46Z das $
+ */
+
+#ifndef _MACHINE_IEEEFP_H_
+#define _MACHINE_IEEEFP_H_
+
+/* Deprecated FPU control interface */
+
+#include <machine/fsr.h>
+
+typedef int fp_except_t;
+#define FP_X_IMP	FSR_NX	/* imprecise (loss of precision) */
+#define FP_X_DZ		FSR_DZ	/* divide-by-zero exception */
+#define FP_X_UFL	FSR_UF	/* underflow exception */
+#define FP_X_OFL	FSR_OF	/* overflow exception */
+#define FP_X_INV	FSR_NV	/* invalid operation exception */
+
+typedef enum {
+	FP_RN = FSR_RD_N,	/* round to nearest representable number */
+	FP_RZ = FSR_RD_Z,	/* round to zero (truncate) */
+	FP_RP = FSR_RD_PINF,	/* round toward positive infinity */
+	FP_RM = FSR_RD_NINF	/* round toward negative infinity */
+} fp_rnd_t;
+
+__BEGIN_DECLS
+extern fp_rnd_t    fpgetround(void);
+extern fp_rnd_t    fpsetround(fp_rnd_t);
+extern fp_except_t fpgetmask(void);
+extern fp_except_t fpsetmask(fp_except_t);
+extern fp_except_t fpgetsticky(void);
+__END_DECLS
+
+
+#endif /* _MACHINE_IEEEFP_H_ */


Property changes on: trunk/sys/sparc64/include/ieeefp.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/in_cksum.h
===================================================================
--- trunk/sys/sparc64/include/in_cksum.h	                        (rev 0)
+++ trunk/sys/sparc64/include/in_cksum.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,176 @@
+/* $MidnightBSD$ */
+/*-
+ * 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.
+ * 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.
+ */
+/*-
+ * Copyright (c) 2001 by Thomas Moestl <tmm at 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, 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 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
+ *	from: FreeBSD: src/sys/alpha/include/in_cksum.h,v 1.5 2000/05/06
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/in_cksum.h 235941 2012-05-24 22:00:48Z bz $
+ */
+
+#ifndef _MACHINE_IN_CKSUM_H_
+#define	_MACHINE_IN_CKSUM_H_	1
+
+#include <sys/cdefs.h>
+
+#define	in_cksum(m, len)	in_cksum_skip(m, len, 0)
+
+#if defined(IPVERSION) && (IPVERSION == 4)
+static __inline void
+in_cksum_update(struct ip *ip)
+{
+	int __tmp;
+
+	__tmp = (int)ip->ip_sum + 1;
+	ip->ip_sum = __tmp + (__tmp >> 16);
+}
+#endif
+
+static __inline u_short
+in_addword(u_short sum, u_short b)
+{
+	u_long __ret, __tmp;
+
+	__asm(
+	    "sll %2, 16, %0\n"
+	    "sll %3, 16, %1\n"
+	    "addcc %0, %1, %0\n"
+	    "srl %0, 16, %0\n"
+	    "addc %0, 0, %0\n"
+	    : "=&r" (__ret), "=&r" (__tmp) : "r" (sum), "r" (b) : "cc");
+	return (__ret);
+}
+
+static __inline u_short
+in_pseudo(u_int sum, u_int b, u_int c)
+{
+	u_long __tmp;
+
+	__asm(
+	    "addcc %0, %3, %0\n"
+	    "addccc %0, %4, %0\n"
+	    "addc %0, 0, %0\n"
+	    "sll %0, 16, %1\n"
+	    "addcc %0, %1, %0\n"
+	    "srl %0, 16, %0\n"
+	    "addc %0, 0, %0\n"
+	    : "=r" (sum), "=&r" (__tmp) : "0" (sum), "r" (b), "r" (c) : "cc");
+	return (sum);
+}
+
+#if defined(IPVERSION) && (IPVERSION == 4)
+static __inline u_int
+in_cksum_hdr(struct ip *ip)
+{
+	u_long __ret, __tmp1, __tmp2, __tmp3, __tmp4;
+
+	/*
+	 * Use 32-bit memory accesses and additions - addition with carry only
+	 * works for 32 bits, and fixing up alignment issues for 64 is probably
+	 * more trouble than it's worth.
+	 * This may read outside of the ip header, but does not cross a page
+	 * boundary in doing so, so that should be OK.
+	 * Actually, this specialized implementation might be overkill - using
+	 * a generic implementation for both in_cksum_skip and in_cksum_hdr
+	 * should not be too much more expensive.
+	 */
+#define	__LD_ADD(addr, tmp, sum, offs, mod)				\
+    "lduw [" #addr " + " #offs "], " #tmp "\n"				\
+    "add" # mod " " #sum ", " #tmp ", " #sum "\n"
+
+	__asm(
+	    "and %5, 3, %3\n"
+	    "andn %5, 3, %1\n"
+	    "brz,pt %3, 0f\n"
+	    " lduw [%1], %0\n"
+	    "mov 4, %4\n"
+	    "sub %4, %3, %4\n"
+	    "sll %4, 3, %4\n"		/* fix up unaligned buffers */
+	    "mov 1, %2\n"
+	    "sll %2, %4, %4\n"
+	    "sub %4, 1, %4\n"
+	    "lduw [%1 + 20], %2\n"
+	    "andn %2, %4, %2\n"
+	    "and %0, %4, %0\n"
+	    "or %0, %2, %0\n"
+	    "0:\n"
+	    __LD_ADD(%1, %2, %0, 4, cc)
+	    __LD_ADD(%1, %2, %0, 8, ccc)
+	    __LD_ADD(%1, %2, %0, 12, ccc)
+	    __LD_ADD(%1, %2, %0, 16, ccc)
+	    "addc %0, 0, %0\n"		/* reduce */
+	    "1:\n"
+	    "sll %0, 16, %2\n"
+	    "addcc %0, %2, %0\n"
+	    "srl %0, 16, %0\n"
+	    "addc %0, 0, %0\n"
+	    "andcc %3, 1, %3\n"		/* need to byte-swap? */
+	    "clr %3\n"
+	    "bne,a,pn %%xcc, 1b\n"
+	    " sll %0, 8, %0\n"
+	    "not %0\n"
+	    "sll %0, 16, %0\n"
+	    "srl %0, 16, %0\n"
+	    : "=&r" (__ret), "=r" (__tmp1), "=&r" (__tmp2), "=&r" (__tmp3),
+	    "=&r" (__tmp4) : "1" (ip) : "cc");
+#undef __LD_ADD
+	return (__ret);
+}
+#endif
+
+#ifdef _KERNEL
+u_short	in_cksum_skip(struct mbuf *m, int len, int skip);
+#endif
+
+#endif /* _MACHINE_IN_CKSUM_H_ */


Property changes on: trunk/sys/sparc64/include/in_cksum.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/instr.h
===================================================================
--- trunk/sys/sparc64/include/instr.h	                        (rev 0)
+++ trunk/sys/sparc64/include/instr.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,619 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1994 David S. Miller, davem at nadzieja.rutgers.edu
+ * Copyright (c) 1995 Paul Kranenburg
+ * Copyright (c) 2001 Thomas Moestl <tmm at 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, 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 David Miller.
+ * 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.
+ *
+ *	from: NetBSD: db_disasm.c,v 1.9 2000/08/16 11:29:42 pk Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/instr.h 139825 2005-01-07 02:29:27Z imp $
+ */
+
+#ifndef _MACHINE_INSTR_H_
+#define _MACHINE_INSTR_H_
+
+/*
+ * Definitions for all instruction formats
+ */
+#define	IF_OP_SHIFT		30
+#define	IF_OP_BITS		 2
+#define	IF_IMM_SHIFT		 0	/* Immediate/Displacement */
+
+/*
+ * Definitions for format 2
+ */
+#define	IF_F2_RD_SHIFT		25
+#define	IF_F2_RD_BITS		 5
+#define	IF_F2_A_SHIFT		29
+#define	IF_F2_A_BITS		 1
+#define	IF_F2_COND_SHIFT	25
+#define	IF_F2_COND_BITS		 4
+#define	IF_F2_RCOND_SHIFT	25
+#define	IF_F2_RCOND_BITS	 3
+#define	IF_F2_OP2_SHIFT		22
+#define	IF_F2_OP2_BITS		 3
+#define	IF_F2_CC1_SHIFT		21
+#define	IF_F2_CC1_BITS		 1
+#define	IF_F2_CC0_SHIFT		20
+#define	IF_F2_CC0_BITS		 1
+#define	IF_F2_CC_SHIFT		20	/* CC0 and CC1 combined. */
+#define	IF_F2_CC_BITS		 2
+#define	IF_F2_D16HI_SHIFT	20
+#define	IF_F2_D16HI_BITS	 2
+#define	IF_F2_P_SHIFT		19
+#define	IF_F2_P_BITS		 1
+#define	IF_F2_RS1_SHIFT		14
+#define	IF_F2_RS1_BITS		 5
+
+/*
+ * Definitions for format 3
+ */
+#define	IF_F3_OP3_SHIFT		19
+#define	IF_F3_OP3_BITS		 6
+#define	IF_F3_RD_SHIFT		IF_F2_RD_SHIFT
+#define	IF_F3_RD_BITS		IF_F2_RD_BITS
+#define	IF_F3_FCN_SHIFT		25
+#define	IF_F3_FCN_BITS		 5
+#define	IF_F3_CC1_SHIFT		26
+#define	IF_F3_CC1_BITS		 1
+#define	IF_F3_CC0_SHIFT		25
+#define	IF_F3_CC0_BITS		 1
+#define	IF_F3_CC_SHIFT		25	/* CC0 and CC1 combined. */
+#define	IF_F3_CC_BITS		 2
+#define	IF_F3_RS1_SHIFT		IF_F2_RS1_SHIFT
+#define	IF_F3_RS1_BITS		IF_F2_RS1_BITS
+#define	IF_F3_I_SHIFT		13
+#define	IF_F3_I_BITS		 1
+#define	IF_F3_X_SHIFT		12
+#define	IF_F3_X_BITS		 1
+#define	IF_F3_RCOND_SHIFT	10
+#define	IF_F3_RCOND_BITS	 3
+#define	IF_F3_IMM_ASI_SHIFT	 5
+#define	IF_F3_IMM_ASI_BITS	 8
+#define	IF_F3_OPF_SHIFT		 5
+#define	IF_F3_OPF_BITS		 9
+#define	IF_F3_CMASK_SHIFT	 4
+#define	IF_F3_CMASK_BITS	 3
+#define	IF_F3_RS2_SHIFT		 0
+#define	IF_F3_RS2_BITS		 5
+#define	IF_F3_SHCNT32_SHIFT	 0
+#define	IF_F3_SHCNT32_BITS	 5
+#define	IF_F3_SHCNT64_SHIFT	 0
+#define	IF_F3_SHCNT64_BITS	 6
+
+/*
+ * Definitions for format 4
+ */
+#define	IF_F4_OP3_SHIFT		IF_F3_OP3_SHIFT
+#define	IF_F4_OP3_BITS		IF_F3_OP3_BITS
+#define	IF_F4_RD_SHIFT		IF_F2_RD_SHIFT
+#define	IF_F4_RD_BITS		IF_F2_RD_BITS
+#define	IF_F4_RS1_SHIFT		IF_F2_RS1_SHIFT
+#define	IF_F4_RS1_BITS		IF_F2_RS1_BITS
+#define	IF_F4_TCOND_SHIFT	IF_F2_COND_SHIFT	/* cond for Tcc */
+#define	IF_F4_TCOND_BITS	IF_F2_COND_BITS
+#define	IF_F4_CC2_SHIFT		18
+#define	IF_F4_CC2_BITS		 1
+#define	IF_F4_COND_SHIFT	14
+#define	IF_F4_COND_BITS		 4
+#define	IF_F4_I_SHIFT		IF_F3_I_SHIFT
+#define	IF_F4_I_BITS		IF_F3_I_BITS
+#define	IF_F4_OPF_CC_SHIFT	11
+#define	IF_F4_OPF_CC_BITS	 3
+#define	IF_F4_CC1_SHIFT		12
+#define	IF_F4_CC1_BITS		 1
+#define	IF_F4_CC0_SHIFT		11
+#define	IF_F4_CC0_BITS		 1
+#define	IF_F4_RCOND_SHIFT	IF_F3_RCOND_SHIFT
+#define	IF_F4_RCOND_BITS	IF_F3_RCOND_BITS
+#define	IF_F4_OPF_LOW_SHIFT	 5
+#define	IF_F4_RS2_SHIFT		IF_F3_RS2_SHIFT
+#define	IF_F4_RS2_BITS		IF_F3_RS2_BITS
+#define	IF_F4_SW_TRAP_SHIFT	 0
+#define	IF_F4_SW_TRAP_BITS	 7
+
+/*
+ * Macros to decode instructions
+ */
+/* Extract a field */
+#define	IF_MASK(s, w)		(((1 << (w)) - 1) << (s))
+#define	IF_EXTRACT(x, s, w)	(((x) & IF_MASK((s), (w))) >> (s))
+#define	IF_DECODE(x, f) \
+	IF_EXTRACT((x), IF_ ## f ## _SHIFT, IF_ ## f ## _BITS)
+
+/* Sign-extend a field of width W */
+#define	IF_SEXT(x, w) \
+	(((x) & (1L << ((w) - 1))) != 0 ? \
+	    (-1L - ((x) ^ ((1L << (w)) - 1))) : (x))
+
+#if 0
+/*
+ * The following C variant is from db_disassemble.c, and surely faster, but it
+ * relies on behaviour that is undefined by the C standard (>> in conjunction
+ * with signed negative arguments).
+ */
+#define	IF_SEXT(v, w)	((((long long)(v)) << (64 - w)) >> (64 - w))
+/* Assembler version of the above */
+#define	IF_SEXT(v, w) \
+	{ u_long t; ( __asm __volatile("sllx %1, %2, %0; srax %0, %2, %0" :
+	    "=r" (t) : "r" (v) : "i" (64 - w)); t)}
+#endif
+
+/* All instruction formats */
+#define	IF_OP(i)		IF_DECODE(i, OP)
+
+/* Instruction format 2 */
+#define	IF_F2_RD(i)		IF_DECODE((i), F2_RD)
+#define	IF_F2_A(i)		IF_DECODE((i), F2_A)
+#define	IF_F2_COND(i)		IF_DECODE((i), F2_COND)
+#define	IF_F2_RCOND(i)		IF_DECODE((i), F2_RCOND)
+#define	IF_F2_OP2(i)		IF_DECODE((i), F2_OP2)
+#define	IF_F2_CC1(i)		IF_DECODE((i), F2_CC1)
+#define	IF_F2_CC0(i)		IF_DECODE((i), F2_CC0)
+#define	IF_F2_CC(i)		IF_DECODE((i), F2_CC)
+#define	IF_F2_D16HI(i)		IF_DECODE((i), F2_D16HI)
+#define	IF_F2_P(i)		IF_DECODE((i), F2_P)
+#define	IF_F2_RS1(i)		IF_DECODE((i), F2_RS1)
+
+/* Instruction format 3 */
+#define	IF_F3_OP3(i)		IF_DECODE((i), F3_OP3)
+#define	IF_F3_RD(i)		IF_F2_RD((i))
+#define	IF_F3_FCN(i)		IF_DECODE((i), F3_FCN)
+#define	IF_F3_CC1(i)		IF_DECODE((i), F3_CC1)
+#define	IF_F3_CC0(i)		IF_DECODE((i), F3_CC0)
+#define	IF_F3_CC(i)		IF_DECODE((i), F3_CC)
+#define	IF_F3_RS1(i)		IF_F2_RS1((i))
+#define	IF_F3_I(i)		IF_DECODE((i), F3_I)
+#define	IF_F3_X(i)		IF_DECODE((i), F3_X)
+#define	IF_F3_RCOND(i)		IF_DECODE((i), F3_RCOND)
+#define	IF_F3_IMM_ASI(i)	IF_DECODE((i), F3_IMM_ASI)
+#define	IF_F3_OPF(i)		IF_DECODE((i), F3_OPF)
+#define	IF_F3_CMASK(i)		IF_DECODE((i), F3_CMASK)
+#define	IF_F3_RS2(i)		IF_DECODE((i), F3_RS2)
+#define	IF_F3_SHCNT32(i)	IF_DECODE((i), F3_SHCNT32)
+#define	IF_F3_SHCNT64(i)	IF_DECODE((i), F3_SHCNT64)
+
+/* Instruction format 4 */
+#define	IF_F4_OP3(i)		IF_F3_OP3((i))
+#define	IF_F4_RD(i)		IF_F3_RD((i))
+#define	IF_F4_TCOND(i)		IF_DECODE((i), F4_TCOND)
+#define	IF_F4_RS1(i)		IF_F3_RS1((i))
+#define	IF_F4_CC2(i)		IF_DECODE((i), F4_CC2)
+#define	IF_F4_COND(i)		IF_DECODE((i), F4_COND)
+#define	IF_F4_I(i)		IF_F3_I((i))
+#define	IF_F4_OPF_CC(i)		IF_DECODE((i), F4_OPF_CC)
+#define	IF_F4_RCOND(i)		IF_F3_RCOND((i))
+#define	IF_F4_OPF_LOW(i, w)	IF_EXTRACT((i), IF_F4_OPF_LOW_SHIFT, (w))
+#define	IF_F4_RS2(i)		IF_F3_RS2((i))
+#define	IF_F4_SW_TRAP(i)	IF_DECODE((i), F4_SW_TRAP)
+
+/* Extract an immediate from an instruction, with an without sign extension */
+#define	IF_IMM(i, w)	IF_EXTRACT((i), IF_IMM_SHIFT, (w))
+#define	IF_SIMM(i, w)	({ u_long b = (w), x = IF_IMM((i), b); IF_SEXT((x), b); })
+
+/*
+ * Macros to encode instructions
+ */
+#define	IF_INSERT(x, s, w)	(((x) & ((1 << (w)) - 1)) << (s))
+#define	IF_ENCODE(x, f) \
+	IF_INSERT((x), IF_ ## f ## _SHIFT, IF_ ## f ## _BITS)
+
+/* All instruction formats */
+#define	EIF_OP(x)		IF_ENCODE((x), OP)
+
+/* Instruction format 2 */
+#define	EIF_F2_RD(x)		IF_ENCODE((x), F2_RD)
+#define	EIF_F2_A(x)		IF_ENCODE((x), F2_A)
+#define	EIF_F2_COND(x)		IF_ENCODE((x), F2_COND)
+#define	EIF_F2_RCOND(x)		IF_ENCODE((x), F2_RCOND)
+#define	EIF_F2_OP2(x)		IF_ENCODE((x), F2_OP2)
+#define	EIF_F2_CC1(x)		IF_ENCODE((x), F2_CC1)
+#define	EIF_F2_CC0(x)		IF_ENCODE((x), F2_CC0)
+#define	EIF_F2_D16HI(x)		IF_ENCODE((x), F2_D16HI)
+#define	EIF_F2_P(x)		IF_ENCODE((x), F2_P)
+#define	EIF_F2_RS1(x)		IF_ENCODE((x), F2_RS1)
+
+/* Instruction format 3 */
+#define	EIF_F3_OP3(x)		IF_ENCODE((x), F3_OP3)
+#define	EIF_F3_RD(x)		EIF_F2_RD((x))
+#define	EIF_F3_FCN(x)		IF_ENCODE((x), F3_FCN)
+#define	EIF_F3_CC1(x)		IF_ENCODE((x), F3_CC1)
+#define	EIF_F3_CC0(x)		IF_ENCODE((x), F3_CC0)
+#define	EIF_F3_RS1(x)		EIF_F2_RS1((x))
+#define	EIF_F3_I(x)		IF_ENCODE((x), F3_I)
+#define	EIF_F3_X(x)		IF_ENCODE((x), F3_X)
+#define	EIF_F3_RCOND(x)		IF_ENCODE((x), F3_RCOND)
+#define	EIF_F3_IMM_ASI(x)	IF_ENCODE((x), F3_IMM_ASI)
+#define	EIF_F3_OPF(x)		IF_ENCODE((x), F3_OPF)
+#define	EIF_F3_CMASK(x)		IF_ENCODE((x), F3_CMASK)
+#define	EIF_F3_RS2(x)		IF_ENCODE((x), F3_RS2)
+#define	EIF_F3_SHCNT32(x)	IF_ENCODE((x), F3_SHCNT32)
+#define	EIF_F3_SHCNT64(x)	IF_ENCODE((x), F3_SHCNT64)
+
+/* Instruction format 4 */
+#define	EIF_F4_OP3(x)		EIF_F3_OP3((x))
+#define	EIF_F4_RD(x)		EIF_F2_RD((x))
+#define	EIF_F4_TCOND(x)		IF_ENCODE((x), F4_TCOND)
+#define	EIF_F4_RS1(x)		EIF_F2_RS1((x))
+#define	EIF_F4_CC2(x)		IF_ENCODE((x), F4_CC2)
+#define	EIF_F4_COND(x)		IF_ENCODE((x), F4_COND)
+#define	EIF_F4_I(x)		EIF_F3_I((x))
+#define	EIF_F4_OPF_CC(x)	IF_ENCODE((x), F4_OPF_CC)
+#define	EIF_F4_RCOND(x)		EIF_F3_RCOND((x))
+#define	EIF_F4_OPF_LOW(i, w)	IF_INSERT((x), IF_F4_OPF_CC_SHIFT, (w))
+#define	EIF_F4_RS2(x)		EIF_F3_RS2((x))
+#define	EIF_F4_SW_TRAP(x)	IF_ENCODE((x), F4_SW_TRAP)
+
+/* Immediates */
+#define	EIF_IMM(x, w)	IF_INSERT((x), IF_IMM_SHIFT, (w))
+#define	EIF_SIMM(x, w)	IF_EIMM((x), (w))
+
+/*
+ * OP field values (specifying the instruction format)
+ */
+#define	IOP_FORM2		0x00	/* Format 2: sethi, branches */
+#define	IOP_CALL		0x01	/* Format 1: call */
+#define	IOP_MISC		0x02	/* Format 3 or 4: arith & misc */
+#define	IOP_LDST		0x03	/* Format 4: loads and stores */
+
+/*
+ * OP2/OP3 values (specifying the actual instruction)
+ */
+/* OP2 values for format 2 (OP = 0) */
+#define	INS0_ILLTRAP		0x00
+#define	INS0_BPcc		0x01
+#define	INS0_Bicc		0x02
+#define	INS0_BPr		0x03
+#define	INS0_SETHI	       	0x04	/* with rd = 0 and imm22 = 0, nop */
+#define	INS0_FBPfcc		0x05
+#define	INS0_FBfcc		0x06
+/* undefined			0x07 */
+
+/* OP3 values for Format 3 and 4 (OP = 2) */
+#define	INS2_ADD		0x00
+#define	INS2_AND		0x01
+#define	INS2_OR			0x02
+#define	INS2_XOR		0x03
+#define	INS2_SUB		0x04
+#define	INS2_ANDN		0x05
+#define	INS2_ORN		0x06
+#define	INS2_XNOR		0x07
+#define	INS2_ADDC		0x08
+#define	INS2_MULX		0x09
+#define	INS2_UMUL		0x0a
+#define	INS2_SMUL		0x0b
+#define	INS2_SUBC		0x0c
+#define	INS2_UDIVX		0x0d
+#define	INS2_UDIV		0x0e
+#define	INS2_SDIV		0x0f
+#define	INS2_ADDcc		0x10
+#define	INS2_ANDcc		0x11
+#define	INS2_ORcc		0x12
+#define	INS2_XORcc		0x13
+#define	INS2_SUBcc		0x14
+#define	INS2_ANDNcc		0x15
+#define	INS2_ORNcc		0x16
+#define	INS2_XNORcc		0x17
+#define	INS2_ADDCcc		0x18
+/* undefined			0x19 */
+#define	INS2_UMULcc		0x1a
+#define	INS2_SMULcc		0x1b
+#define	INS2_SUBCcc		0x1c
+/* undefined			0x1d */
+#define	INS2_UDIVcc		0x1e
+#define	INS2_SDIVcc		0x1f
+#define	INS2_TADDcc		0x20
+#define	INS2_TSUBcc		0x21
+#define	INS2_TADDccTV		0x22
+#define	INS2_TSUBccTV		0x23
+#define	INS2_MULScc		0x24
+#define	INS2_SSL		0x25	/* SLLX when IF_X(i) == 1 */
+#define	INS2_SRL		0x26	/* SRLX when IF_X(i) == 1 */
+#define	INS2_SRA		0x27	/* SRAX when IF_X(i) == 1 */
+#define	INS2_RD			0x28	/* and MEMBAR, STBAR */
+/* undefined			0x29 */
+#define	INS2_RDPR		0x2a
+#define	INS2_FLUSHW		0x2b
+#define	INS2_MOVcc		0x2c
+#define	INS2_SDIVX		0x2d
+#define	INS2_POPC		0x2e	/* undefined if IF_RS1(i) != 0 */
+#define	INS2_MOVr		0x2f
+#define	INS2_WR			0x30	/* and SIR */
+#define	INS2_SV_RSTR		0x31	/* saved, restored */
+#define	INS2_WRPR		0x32
+/* undefined			0x33 */
+#define	INS2_FPop1		0x34	/* further encoded in opf field */
+#define	INS2_FPop2		0x35	/* further encoded in opf field */
+#define	INS2_IMPLDEP1		0x36
+#define	INS2_IMPLDEP2		0x37
+#define	INS2_JMPL		0x38
+#define	INS2_RETURN		0x39
+#define	INS2_Tcc		0x3a
+#define	INS2_FLUSH		0x3b
+#define	INS2_SAVE		0x3c
+#define	INS2_RESTORE		0x3d
+#define	INS2_DONE_RETR		0x3e	/* done, retry */
+/* undefined			0x3f */
+
+/* OP3 values for format 3 (OP = 3) */
+#define	INS3_LDUW		0x00
+#define	INS3_LDUB		0x01
+#define	INS3_LDUH		0x02
+#define	INS3_LDD		0x03
+#define	INS3_STW		0x04
+#define	INS3_STB		0x05
+#define	INS3_STH		0x06
+#define	INS3_STD		0x07
+#define	INS3_LDSW		0x08
+#define	INS3_LDSB		0x09
+#define	INS3_LDSH		0x0a
+#define	INS3_LDX		0x0b
+/* undefined			0x0c */
+#define	INS3_LDSTUB		0x0d
+#define	INS3_STX		0x0e
+#define	INS3_SWAP		0x0f
+#define	INS3_LDUWA		0x10
+#define	INS3_LDUBA		0x11
+#define	INS3_LDUHA		0x12
+#define	INS3_LDDA		0x13
+#define	INS3_STWA		0x14
+#define	INS3_STBA		0x15
+#define	INS3_STHA		0x16
+#define	INS3_STDA		0x17
+#define	INS3_LDSWA		0x18
+#define	INS3_LDSBA		0x19
+#define	INS3_LDSHA		0x1a
+#define	INS3_LDXA		0x1b
+/* undefined			0x1c */
+#define	INS3_LDSTUBA		0x1d
+#define	INS3_STXA		0x1e
+#define	INS3_SWAPA		0x1f
+#define	INS3_LDF		0x20
+#define	INS3_LDFSR		0x21	/* and LDXFSR */
+#define	INS3_LDQF		0x22
+#define	INS3_LDDF		0x23
+#define	INS3_STF		0x24
+#define	INS3_STFSR		0x25	/* and STXFSR */
+#define	INS3_STQF		0x26
+#define	INS3_STDF		0x27
+/* undefined			0x28 - 0x2c */
+#define	INS3_PREFETCH		0x2d
+/* undefined			0x2e - 0x2f */
+#define	INS3_LDFA		0x30
+/* undefined			0x31 */
+#define	INS3_LDQFA		0x32
+#define	INS3_LDDFA		0x33
+#define	INS3_STFA		0x34
+/* undefined			0x35 */
+#define	INS3_STQFA		0x36
+#define	INS3_STDFA		0x37
+/* undefined			0x38 - 0x3b */
+#define	INS3_CASA		0x39
+#define	INS3_PREFETCHA		0x3a
+#define	INS3_CASXA		0x3b
+
+/*
+ * OPF values (floating point instructions, IMPLDEP)
+ */
+/*
+ * These values are or'ed to the FPop values to get the instructions.
+ * They describe the operand type(s).
+ */
+#define	INSFP_i			0x000	/* 32-bit int */
+#define	INSFP_s			0x001	/* 32-bit single */
+#define	INSFP_d			0x002	/* 64-bit double */
+#define	INSFP_q			0x003	/* 128-bit quad */
+/* FPop1. The comments give the types for which this instruction is defined. */
+#define	INSFP1_FMOV		0x000	/* s, d, q */
+#define	INSFP1_FNEG		0x004	/* s, d, q */
+#define	INSFP1_FABS		0x008	/* s, d, q */
+#define	INSFP1_FSQRT		0x028	/* s, d, q */
+#define	INSFP1_FADD		0x040	/* s, d, q */
+#define	INSFP1_FSUB		0x044	/* s, d, q */
+#define	INSFP1_FMUL		0x048	/* s, d, q */
+#define	INSFP1_FDIV		0x04c	/* s, d, q */
+#define	INSFP1_FsMULd		0x068	/* s */
+#define	INSFP1_FdMULq		0x06c	/* d */
+#define	INSFP1_FTOx		0x080	/* s, d, q */
+#define	INSFP1_FxTOs		0x084	/* special: i only */
+#define	INSFP1_FxTOd		0x088	/* special: i only */
+#define	INSFP1_FxTOq		0x08c	/* special: i only */
+#define	INSFP1_FTOs		0x0c4	/* i, d, q */
+#define	INSFP1_FTOd		0x0c8	/* i, s, q */
+#define	INSFP1_FTOq		0x0cc	/* i, s, d */
+#define	INSFP1_FTOi		0x0d0	/* i, s, d */
+
+/* FPop2 */
+#define	INSFP2_FMOV_CCMUL	0x40
+#define	INSFP2_FMOV_CCOFFS	0x00
+/* Use the IFCC_* constants for cc. Operand types: s, d, q */
+#define	INSFP2_FMOV_CC(cc)	((cc) * INSFP2_FMOV_CCMUL + INSFP2_FMOV_CCOFFS)
+#define	INSFP2_FMOV_RCMUL	0x20
+#define	INSFP2_FMOV_RCOFFS	0x04
+/* Use the IRCOND_* constants for rc. Operand types: s, d, q */
+#define	INSFP2_FMOV_RC(rc)	((rc) * INSFP2_FMOV_RCMUL + INSFP2_FMOV_RCOFFS)
+#define	INSFP2_FCMP		0x050	/* s, d, q */
+#define	INSFP2_FCMPE		0x054	/* s, d, q */
+
+/* Decode 5-bit register field into 6-bit number (for doubles and quads). */
+#define	INSFPdq_RN(rn)		(((rn) & ~1) | (((rn) & 1) << 5))
+
+/* IMPLDEP1 for Sun UltraSparc */
+#define	IIDP1_EDGE8		0x00
+#define	IIDP1_EDGE8N		0x01	/* US-III */
+#define	IIDP1_EDGE8L		0x02
+#define	IIDP1_EDGE8LN		0x03	/* US-III */
+#define	IIDP1_EDGE16		0x04
+#define	IIDP1_EDGE16N		0x05	/* US-III */
+#define	IIDP1_EDGE16L		0x06
+#define	IIDP1_EDGE16LN		0x07	/* US-III */
+#define	IIDP1_EDGE32		0x08
+#define	IIDP1_EDGE32N		0x09	/* US-III */
+#define	IIDP1_EDGE32L		0x0a
+#define	IIDP1_EDGE32LN		0x0b	/* US-III */
+#define	IIDP1_ARRAY8		0x10
+#define	IIDP1_ARRAY16		0x12
+#define	IIDP1_ARRAY32		0x14
+#define	IIDP1_ALIGNADDRESS	0x18
+#define	IIDP1_BMASK		0x19	/* US-III */
+#define	IIDP1_ALIGNADDRESS_L	0x1a
+#define	IIDP1_FCMPLE16		0x20
+#define	IIDP1_FCMPNE16		0x22
+#define	IIDP1_FCMPLE32		0x24
+#define	IIDP1_FCMPNE32		0x26
+#define	IIDP1_FCMPGT16		0x28
+#define	IIDP1_FCMPEQ16		0x2a
+#define	IIDP1_FCMPGT32		0x2c
+#define	IIDP1_FCMPEQ32		0x2e
+#define	IIDP1_FMUL8x16		0x31
+#define	IIDP1_FMUL8x16AU	0x33
+#define	IIDP1_FMUL8X16AL	0x35
+#define	IIDP1_FMUL8SUx16	0x36
+#define	IIDP1_FMUL8ULx16	0x37
+#define	IIDP1_FMULD8SUx16	0x38
+#define	IIDP1_FMULD8ULx16	0x39
+#define	IIDP1_FPACK32		0x3a
+#define	IIDP1_FPACK16		0x3b
+#define	IIDP1_FPACKFIX		0x3d
+#define	IIDP1_PDIST		0x3e
+#define	IIDP1_FALIGNDATA	0x48
+#define	IIDP1_FPMERGE		0x4b
+#define	IIDP1_BSHUFFLE		0x4c	/* US-III */
+#define	IIDP1_FEXPAND		0x4d
+#define	IIDP1_FPADD16		0x50
+#define	IIDP1_FPADD16S		0x51
+#define	IIDP1_FPADD32		0x52
+#define	IIDP1_FPADD32S		0x53
+#define	IIDP1_SUB16		0x54
+#define	IIDP1_SUB16S		0x55
+#define	IIDP1_SUB32		0x56
+#define	IIDP1_SUB32S		0x57
+#define	IIDP1_FZERO		0x60
+#define	IIDP1_FZEROS		0x61
+#define	IIDP1_FNOR		0x62
+#define	IIDP1_FNORS		0x63
+#define	IIDP1_FANDNOT2		0x64
+#define	IIDP1_FANDNOT2S		0x65
+#define	IIDP1_NOT2		0x66
+#define	IIDP1_NOT2S		0x67
+#define	IIDP1_FANDNOT1		0x68
+#define	IIDP1_FANDNOT1S		0x69
+#define	IIDP1_FNOT1		0x6a
+#define	IIDP1_FNOT1S		0x6b
+#define	IIDP1_FXOR		0x6c
+#define	IIDP1_FXORS		0x6d
+#define	IIDP1_FNAND		0x6e
+#define	IIDP1_FNANDS		0x6f
+#define	IIDP1_FAND		0x70
+#define	IIDP1_FANDS		0x71
+#define	IIDP1_FXNOR		0x72
+#define	IIDP1_FXNORS		0x73
+#define	IIDP1_FSRC1		0x74
+#define	IIDP1_FSRC1S		0x75
+#define	IIDP1_FORNOT2		0x76
+#define	IIDP1_FORNOT2S		0x77
+#define	IIDP1_FSRC2		0x78
+#define	IIDP1_FSRC2S		0x79
+#define	IIDP1_FORNOT1		0x7a
+#define	IIDP1_FORNOT1S		0x7b
+#define	IIDP1_FOR		0x7c
+#define	IIDP1_FORS		0x7d
+#define	IIDP1_FONE		0x7e
+#define	IIDP1_FONES		0x7f
+#define	IIDP1_SHUTDOWN		0x80
+#define	IIDP1_SIAM		0x81	/* US-III */
+
+/*
+ * Instruction modifiers
+ */
+/* cond values for integer ccr's */
+#define	IICOND_N		0x00
+#define	IICOND_E		0x01
+#define	IICOND_LE		0x02
+#define	IICOND_L		0x03
+#define	IICOND_LEU		0x04
+#define	IICOND_CS		0x05
+#define	IICOND_NEG		0x06
+#define	IICOND_VS		0x07
+#define	IICOND_A		0x08
+#define	IICOND_NE		0x09
+#define	IICOND_G		0x0a
+#define	IICOND_GE		0x0b
+#define	IICOND_GU		0x0c
+#define	IICOND_CC		0x0d
+#define	IICOND_POS		0x0e
+#define	IICOND_VC		0x0f
+
+/* cond values for fp ccr's */
+#define	IFCOND_N		0x00
+#define	IFCOND_NE		0x01
+#define	IFCOND_LG		0x02
+#define	IFCOND_UL		0x03
+#define	IFCOND_L		0x04
+#define	IFCOND_UG		0x05
+#define	IFCOND_G		0x06
+#define	IFCOND_U		0x07
+#define	IFCOND_A		0x08
+#define	IFCOND_E		0x09
+#define	IFCOND_UE		0x0a
+#define	IFCOND_GE		0x0b
+#define	IFCOND_UGE		0x0c
+#define	IFCOND_LE		0x0d
+#define	IFCOND_ULE		0x0e
+#define	IFCOND_O		0x0f
+
+/* rcond values for BPr, MOVr, FMOVr */
+#define	IRCOND_Z		0x01
+#define	IRCOND_LEZ		0x02
+#define	IRCOND_LZ		0x03
+#define	IRCOND_NZ		0x05
+#define	IRCOND_GZ		0x06
+#define	IRCOND_GEZ		0x07
+
+/* cc values for MOVcc and FMOVcc */
+#define	IFCC_ICC		0x04
+#define	IFCC_XCC		0x06
+/* if true, the lower 2 bits are the fcc number */
+#define	IFCC_FCC(c)		((c) & 3)
+#define	IFCC_GET_FCC(c)		((c) & 3)
+#define	IFCC_ISFCC(c)		(((c) & 4) == 0)
+
+/* cc values for BPc and Tcc */
+#define	IBCC_ICC		0x00
+#define	IBCC_XCC		0x02
+
+/*
+ * Integer registers
+ */
+#define	IREG_G0			0x00
+#define	IREG_O0			0x08
+#define	IREG_L0			0x10
+#define	IREQ_I0			0x18
+
+#endif /* !_MACHINE_INSTR_H_ */


Property changes on: trunk/sys/sparc64/include/instr.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/intr_machdep.h
===================================================================
--- trunk/sys/sparc64/include/intr_machdep.h	                        (rev 0)
+++ trunk/sys/sparc64/include/intr_machdep.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,114 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/intr_machdep.h 241780 2012-10-20 12:07:48Z marius $
+ */
+
+#ifndef	_MACHINE_INTR_MACHDEP_H_
+#define	_MACHINE_INTR_MACHDEP_H_
+
+#define	IRSR_BUSY	(1 << 5)
+
+#define	PIL_MAX		(1 << 4)
+#define	IV_MAX		(1 << 11)
+
+#define	IR_FREE		(PIL_MAX * 2)
+
+#define	IH_SHIFT	PTR_SHIFT
+#define	IQE_SHIFT	5
+#define	IV_SHIFT	6
+
+#define	PIL_LOW		1	/* stray interrupts */
+#define	PIL_PREEMPT	2	/* preempt idle thread CPU IPI */
+#define	PIL_ITHREAD	3	/* interrupts that use ithreads */
+#define	PIL_RENDEZVOUS	4	/* SMP rendezvous IPI */
+#define	PIL_AST		5	/* asynchronous trap IPI */
+#define	PIL_HARDCLOCK	6	/* hardclock broadcast */
+#define	PIL_FILTER	11	/* filter interrupts */
+#define	PIL_BRIDGE	12	/* bridge interrupts */
+#define	PIL_STOP	13	/* stop CPU IPI */
+#define	PIL_TICK	14	/* tick interrupts */
+
+#ifndef LOCORE
+
+#define	INTR_BRIDGE	INTR_MD1
+
+struct trapframe;
+
+typedef	void ih_func_t(struct trapframe *);
+typedef	void iv_func_t(void *);
+
+struct intr_request {
+	struct	intr_request *ir_next;
+	iv_func_t *ir_func;
+	void	*ir_arg;
+	u_int	ir_vec;
+	u_int	ir_pri;
+};
+
+struct intr_controller {
+	void	(*ic_enable)(void *);
+	void	(*ic_disable)(void *);
+	void	(*ic_assign)(void *);
+	void	(*ic_clear)(void *);
+};
+
+struct intr_vector {
+	iv_func_t *iv_func;
+	void	*iv_arg;
+	const struct	intr_controller *iv_ic;
+	void	*iv_icarg;
+	struct	intr_event *iv_event;
+	u_int	iv_pri;
+	u_int	iv_vec;
+	u_int	iv_mid;
+	u_int	iv_refcnt;
+	u_int	iv_pad[2];
+};
+
+extern ih_func_t *intr_handlers[];
+extern struct intr_vector intr_vectors[];
+
+#ifdef SMP
+void	intr_add_cpu(u_int cpu);
+#endif
+int	intr_bind(int vec, u_char cpu);
+int	intr_describe(int vec, void *ih, const char *descr);
+void	intr_setup(int level, ih_func_t *ihf, int pri, iv_func_t *ivf,
+	    void *iva);
+void	intr_init1(void);
+void	intr_init2(void);
+int	intr_controller_register(int vec, const struct intr_controller *ic,
+	    void *icarg);
+int	inthand_add(const char *name, int vec, int (*filt)(void *),
+	    void (*handler)(void *), void *arg, int flags, void **cookiep);
+int	inthand_remove(int vec, void *cookie);
+
+ih_func_t intr_fast;
+
+#endif /* !LOCORE */
+
+#endif /* !_MACHINE_INTR_MACHDEP_H_ */


Property changes on: trunk/sys/sparc64/include/intr_machdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/iommureg.h
===================================================================
--- trunk/sys/sparc64/include/iommureg.h	                        (rev 0)
+++ trunk/sys/sparc64/include/iommureg.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,213 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 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: @(#)sbusreg.h	8.1 (Berkeley) 6/11/93
+ *	from: NetBSD: iommureg.h,v 1.6 2001/07/20 00:07:13 eeh Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/iommureg.h 218909 2011-02-21 09:01:34Z brucec $
+ */
+
+#ifndef _MACHINE_IOMMUREG_H_
+#define	_MACHINE_IOMMUREG_H_
+
+/*
+ * UltraSPARC IOMMU registers, common to both the PCI and SBus
+ * controllers.
+ */
+
+/* IOMMU registers */
+#define	IMR_CTL		0x0000	/* IOMMU control register */
+#define	IMR_TSB		0x0008	/* IOMMU TSB base register */
+#define	IMR_FLUSH	0x0010	/* IOMMU flush register */
+/* The TTE Cache is Fire and Oberon only. */
+#define	IMR_CACHE_FLUSH	0x0100	/* IOMMU TTE cache flush address register */
+#define	IMR_CACHE_INVAL	0x0108	/* IOMMU TTE cache invalidate register */
+
+/* streaming buffer registers */
+#define	ISR_CTL		0x0000	/* streaming buffer control reg */
+#define	ISR_PGFLUSH	0x0008	/* streaming buffer page flush */
+#define	ISR_FLUSHSYNC	0x0010	/* streaming buffer flush sync */
+
+/* streaming buffer diagnostics registers */
+#define	ISD_DATA_DIAG	0x0000	/* streaming buffer data RAM diag 0..127 */
+#define	ISD_ERROR_DIAG	0x0400	/* streaming buffer error status diag 0..127 */
+#define	ISD_PG_TAG_DIAG	0x0800	/* streaming buffer page tag diag 0..15 */
+#define	ISD_LN_TAG_DIAG	0x0900	/* streaming buffer line tag diag 0..15 */
+
+/* streaming buffer control register */
+#define	STRBUF_EN		0x0000000000000001UL
+#define	STRBUF_D		0x0000000000000002UL
+#define	STRBUF_RR_DIS		0x0000000000000004UL
+
+#define	IOMMU_MAXADDR(bits)	((1UL << (bits)) - 1)
+
+/*
+ * control register bits
+ */
+/* Nummber of entries in the IOTSB - pre-Fire only */
+#define	IOMMUCR_TSBSZ_MASK	0x0000000000070000UL
+#define	IOMMUCR_TSBSZ_SHIFT	16
+/* TSB cache snoop enable */
+#define	IOMMUCR_SE		0x0000000000000400UL
+/* Cache modes - Fire and Oberon */
+#define	IOMMUCR_CM_NC_TLB_TBW	0x0000000000000000UL
+#define	IOMMUCR_CM_LC_NTLB_NTBW	0x0000000000000100UL
+#define	IOMMUCR_CM_LC_TLB_TBW	0x0000000000000200UL
+#define	IOMMUCR_CM_C_TLB_TBW	0x0000000000000300UL
+/* IOMMU page size - pre-Fire only */
+#define	IOMMUCR_8KPG		0x0000000000000000UL
+#define	IOMMUCR_64KPG		0x0000000000000004UL
+/* Bypass enable - Fire and Oberon */
+#define	IOMMUCR_BE		0x0000000000000002UL
+/* Diagnostic mode enable - pre-Fire only */
+#define	IOMMUCR_DE		0x0000000000000002UL
+/* IOMMU/translation enable */
+#define	IOMMUCR_EN		0x0000000000000001UL
+
+/*
+ * TSB base register bits
+ */
+ /* TSB base address */
+#define	IOMMUTB_TB_MASK		0x000007ffffffe000UL
+#define	IOMMUTB_TB_SHIFT	13
+/* IOMMU page size - Fire and Oberon */
+#define	IOMMUTB_8KPG		0x0000000000000000UL
+#define	IOMMUTB_64KPG		0x0000000000000100UL
+/* Nummber of entries in the IOTSB - Fire and Oberon */
+#define	IOMMUTB_TSBSZ_MASK	0x0000000000000004UL
+#define	IOMMUTB_TSBSZ_SHIFT	0
+
+/*
+ * TSB size definitions for both control and TSB base register */
+#define	IOMMU_TSB1K		0
+#define	IOMMU_TSB2K		1
+#define	IOMMU_TSB4K		2
+#define	IOMMU_TSB8K		3
+#define	IOMMU_TSB16K		4
+#define	IOMMU_TSB32K		5
+#define	IOMMU_TSB64K		6
+#define	IOMMU_TSB128K		7
+/* Fire and Oberon */
+#define	IOMMU_TSB256K		8
+/* Fire and Oberon */
+#define	IOMMU_TSB512K		9
+#define	IOMMU_TSBENTRIES(tsbsz)						\
+	((1 << (tsbsz)) << (IO_PAGE_SHIFT - IOTTE_SHIFT))
+
+/*
+ * Diagnostic register definitions
+ */
+#define	IOMMU_DTAG_VPNBITS	19
+#define	IOMMU_DTAG_VPNMASK	((1 << IOMMU_DTAG_VPNBITS) - 1)
+#define	IOMMU_DTAG_VPNSHIFT	13
+#define	IOMMU_DTAG_ERRBITS	3
+#define	IOMMU_DTAG_ERRSHIFT	22
+#define	IOMMU_DTAG_ERRMASK						\
+	(((1 << IOMMU_DTAG_ERRBITS) - 1) << IOMMU_DTAG_ERRSHIFT)
+
+#define	IOMMU_DDATA_PGBITS	21
+#define	IOMMU_DDATA_PGMASK	((1 << IOMMU_DDATA_PGBITS) - 1)
+#define	IOMMU_DDATA_PGSHIFT	13
+#define	IOMMU_DDATA_C		(1 << 28)
+#define	IOMMU_DDATA_V		(1 << 30)
+
+/*
+ * IOMMU stuff
+ */
+/* Entry valid */
+#define	IOTTE_V			0x8000000000000000UL
+/* Page size - pre-Fire only */
+#define	IOTTE_64K		0x2000000000000000UL
+#define	IOTTE_8K		0x0000000000000000UL
+/* Streamable page - streaming buffer equipped variants only */
+#define	IOTTE_STREAM		0x1000000000000000UL
+/* Accesses to the same bus segment - SBus only */
+#define	IOTTE_LOCAL		0x0800000000000000UL
+/* Physical address mask (based on Oberon) */
+#define	IOTTE_PAMASK		0x00007fffffffe000UL
+/* Accesses to cacheable space - pre-Fire only */
+#define	IOTTE_C			0x0000000000000010UL
+/* Writeable */
+#define	IOTTE_W			0x0000000000000002UL
+
+/* log2 of the IOMMU TTE size */
+#define	IOTTE_SHIFT		3
+
+/* Streaming buffer line size */
+#define	STRBUF_LINESZ		64
+
+/*
+ * Number of bytes written by a stream buffer flushsync operation to indicate
+ * completion.
+ */
+#define	STRBUF_FLUSHSYNC_NBYTES	STRBUF_LINESZ
+
+/*
+ * On sun4u each bus controller has a separate IOMMU.  The IOMMU has
+ * a TSB which must be page aligned and physically contiguous.  Mappings
+ * can be of 8K IOMMU pages or 64K IOMMU pages.  We use 8K for compatibility
+ * with the CPU's MMU.
+ *
+ * On sysio, psycho, and psycho+, IOMMU TSBs using 8K pages can map the
+ * following size segments:
+ *
+ *	VA size		VA base		TSB size	tsbsize
+ *	--------	--------	---------	-------
+ *	8MB		ff800000	8K		0
+ *	16MB		ff000000	16K		1
+ *	32MB		fe000000	32K		2
+ *	64MB		fc000000	64K		3
+ *	128MB		f8000000	128K		4
+ *	256MB		f0000000	256K		5
+ *	512MB		e0000000	512K		6
+ *	1GB		c0000000	1MB		7
+ *
+ * Unfortunately, sabres on UltraSPARC IIi and IIe processors does not use
+ * this scheme to determine the IOVA base address.  Instead, bits 31-29 are
+ * used to check against the Target Address Space register in the IIi and
+ * the IOMMU is used if they hit.  God knows what goes on in the IIe.
+ *
+ */
+
+#define	IOTSB_BASESZ		(1024 << IOTTE_SHIFT)
+#define	IOTSB_VEND		(~IO_PAGE_MASK)
+#define	IOTSB_VSTART(sz)	(u_int)(IOTSB_VEND << ((sz) + 10))
+
+#define	MAKEIOTTE(pa, w, c, s)						\
+	(((pa) & IOTTE_PAMASK) | ((w) ? IOTTE_W : 0) |			\
+	((c) ? IOTTE_C : 0) | ((s) ? IOTTE_STREAM : 0) |		\
+	(IOTTE_V | IOTTE_8K))
+#define	IOTSBSLOT(va)							\
+	((u_int)(((vm_offset_t)(va)) - (is->is_dvmabase)) >> IO_PAGE_SHIFT)
+
+#endif /* !_MACHINE_IOMMUREG_H_ */


Property changes on: trunk/sys/sparc64/include/iommureg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/iommuvar.h
===================================================================
--- trunk/sys/sparc64/include/iommuvar.h	                        (rev 0)
+++ trunk/sys/sparc64/include/iommuvar.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,114 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999 Matthew R. Green
+ * 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 ``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.
+ *
+ *	from: NetBSD: iommuvar.h,v 1.6 2008/05/29 14:51:26 mrg Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/iommuvar.h 219567 2011-03-12 14:33:32Z marius $
+ */
+
+#ifndef _MACHINE_IOMMUVAR_H_
+#define	_MACHINE_IOMMUVAR_H_
+
+#define	IO_PAGE_SIZE		PAGE_SIZE_8K
+#define	IO_PAGE_MASK		PAGE_MASK_8K
+#define	IO_PAGE_SHIFT		PAGE_SHIFT_8K
+#define	round_io_page(x)	round_page(x)
+#define	trunc_io_page(x)	trunc_page(x)
+
+/*
+ * LRU queue handling for lazy resource allocation
+ */
+TAILQ_HEAD(iommu_maplruq_head, bus_dmamap);
+
+/*
+ * Per-IOMMU state; the parenthesized comments indicate the locking strategy:
+ *	i - protected by is_mtx.
+ *	r - read-only after initialization.
+ *	* - comment refers to pointer target / target hardware registers
+ *	    (for bus_addr_t).
+ * is_maplruq is also locked by is_mtx.  Elements of is_tsb may only be
+ * accessed from functions operating on the map owning the corresponding
+ * resource, so the locking the user is required to do to protect the
+ * map is sufficient.
+ * dm_reslist of all maps are locked by is_mtx as well.
+ * is_dvma_rman has its own internal lock.
+ */
+struct iommu_state {
+	struct mtx		is_mtx;
+	struct rman		is_dvma_rman;	/* DVMA space rman */
+	struct iommu_maplruq_head is_maplruq;	/* (i) LRU queue */
+	vm_paddr_t		is_ptsb;	/* (r) TSB physical address */
+	uint64_t		*is_tsb;	/* (*i) TSB virtual address */
+	int			is_tsbsize;	/* (r) 0 = 8K, ... */
+	uint64_t		is_pmaxaddr;	/* (r) max. physical address */
+	uint64_t		is_dvmabase;	/* (r) */
+	uint64_t		is_cr;		/* (r) Control reg value */
+
+	vm_paddr_t		is_flushpa[2];	/* (r) */
+	volatile uint64_t	*is_flushva[2];	/* (r, *i) */
+	/*
+	 * (i)
+	 * When a flush is completed, 64 bytes will be stored at the given
+	 * location, the first double word being 1, to indicate completion.
+	 * The lower 6 address bits are ignored, so the addresses need to be
+	 * suitably aligned; over-allocate a large enough margin to be able
+	 * to adjust it.
+	 * Two such buffers are needed.
+	 */
+	volatile char		is_flush[STRBUF_FLUSHSYNC_NBYTES * 3 - 1];
+
+	/* copies of our parent's state, to allow us to be self contained */
+	bus_space_tag_t		is_bustag;	/* (r) Our bus tag */
+	bus_space_handle_t	is_bushandle;	/* (r) */
+	bus_addr_t		is_iommu;	/* (r, *i) IOMMU registers */
+	bus_addr_t		is_sb[2];	/* (r, *i) Streaming buffer */
+	/* Tag diagnostics access */
+	bus_addr_t		is_dtag;	/* (r, *r) */
+	/* Data RAM diagnostic access */
+	bus_addr_t		is_ddram;	/* (r, *r) */
+	/* LRU queue diag. access */
+	bus_addr_t		is_dqueue;	/* (r, *r) */
+	/* Virtual address diagnostics register */
+	bus_addr_t		is_dva;		/* (r, *r) */
+	/* Tag compare diagnostics access */
+	bus_addr_t		is_dtcmp;	/* (r, *r) */
+	/* behavior flags */
+	u_int			is_flags;	/* (r) */
+#define	IOMMU_RERUN_DISABLE	(1 << 0)
+#define	IOMMU_FIRE		(1 << 1)
+#define	IOMMU_FLUSH_CACHE	(1 << 2)
+#define	IOMMU_PRESERVE_PROM	(1 << 3)
+};
+
+/* interfaces for PCI/SBus code */
+void iommu_init(const char *name, struct iommu_state *is, u_int tsbsize,
+    uint32_t iovabase, u_int resvpg);
+void iommu_reset(struct iommu_state *is);
+void iommu_decode_fault(struct iommu_state *is, vm_offset_t phys);
+
+extern struct bus_dma_methods iommu_dma_methods;
+
+#endif /* !_MACHINE_IOMMUVAR_H_ */


Property changes on: trunk/sys/sparc64/include/iommuvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/jbus.h
===================================================================
--- trunk/sys/sparc64/include/jbus.h	                        (rev 0)
+++ trunk/sys/sparc64/include/jbus.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,40 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Marius Strobl <marius at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/jbus.h 203829 2010-02-13 14:13:39Z marius $
+ */
+
+#ifndef _MACHINE_JBUS_H_
+#define	_MACHINE_JBUS_H_
+
+#define	JBUS_CR_JID_SHIFT	(17)
+#define	JBUS_CR_JID_SIZE	(3)
+#define	JBUS_CR_JID_MASK						\
+	(((1 << JBUS_CR_JID_SIZE) - 1) << JBUS_CR_JID_SHIFT)
+
+#define	JBUS_CR_GET_JID(cr)	((cr & JBUS_CR_JID_MASK) >> JBUS_CR_JID_SHIFT)
+
+#endif /* _MACHINE_JBUS_H_ */


Property changes on: trunk/sys/sparc64/include/jbus.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/kdb.h
===================================================================
--- trunk/sys/sparc64/include/kdb.h	                        (rev 0)
+++ trunk/sys/sparc64/include/kdb.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,58 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Marcel Moolenaar
+ * 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 ``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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/kdb.h 170473 2007-06-09 21:55:17Z marcel $
+ */
+
+#ifndef _MACHINE_KDB_H_
+#define _MACHINE_KDB_H_
+
+#include <machine/cpufunc.h>
+
+#define	KDB_STOPPEDPCB(pc)	&stoppcbs[pc->pc_cpuid]
+
+static __inline void
+kdb_cpu_clear_singlestep(void)
+{
+}
+
+static __inline void
+kdb_cpu_set_singlestep(void)
+{
+}
+
+static __inline void
+kdb_cpu_sync_icache(unsigned char *addr, size_t size)
+{
+}
+
+static __inline void
+kdb_cpu_trap(int vector, int _)
+{
+	flushw();
+}
+
+#endif /* _MACHINE_KDB_H_ */


Property changes on: trunk/sys/sparc64/include/kdb.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/kerneldump.h
===================================================================
--- trunk/sys/sparc64/include/kerneldump.h	                        (rev 0)
+++ trunk/sys/sparc64/include/kerneldump.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,52 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 by Thomas Moestl <tmm at 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, 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 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/kerneldump.h 113238 2003-04-08 06:35:09Z jake $
+ */
+
+#ifndef _MACHINE_KERNELDUMP_H_
+#define	_MACHINE_KERNELDUMP_H_
+
+struct sparc64_dump_reg {
+	vm_paddr_t	dr_pa;
+	vm_offset_t	dr_size;
+	vm_offset_t	dr_offs;
+};
+
+/*
+ * Kernel dump format for sparc64. This does not use ELF because it is of no
+ * avail (only libkvm knows how to translate addresses properly anyway) and
+ * would require some ugly hacks.
+ */
+struct sparc64_dump_hdr {
+	vm_offset_t	dh_hdr_size;
+	vm_paddr_t	dh_tsb_pa;
+	vm_size_t	dh_tsb_size;
+	vm_size_t	dh_tsb_mask;
+	int		dh_nregions;
+	struct sparc64_dump_reg	dh_regions[];
+};
+
+#endif /* _MACHINE_KERNELDUMP_H_ */


Property changes on: trunk/sys/sparc64/include/kerneldump.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/ktr.h
===================================================================
--- trunk/sys/sparc64/include/ktr.h	                        (rev 0)
+++ trunk/sys/sparc64/include/ktr.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,100 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1996 Berkeley Software Design, Inc. 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. Berkeley Software Design Inc's name may not be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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 BSDI $Id: ktr.h,v 1.10.2.7 2000/03/16 21:44:42 cp Exp $
+ * $FreeBSD: stable/10/sys/sparc64/include/ktr.h 293853 2016-01-13 21:38:52Z marius $
+ */
+
+#ifndef _MACHINE_KTR_H_
+#define _MACHINE_KTR_H_
+
+#include <sys/ktr.h>
+
+#ifdef LOCORE
+
+/*
+ * XXX could really use another register ...
+ */
+#define	ATR(desc, r1, r2, r3, l1, l2) \
+	.sect	.rodata ; \
+l1:	.asciz	desc ; \
+	.previous ; \
+	SET(ktr_idx, r2, r1) ; \
+	lduw	[r1], r2 ; \
+l2:	add	r2, 1, r3 ; \
+	set	KTR_ENTRIES - 1, r1 ; \
+	and	r3, r1, r3 ; \
+	set	ktr_idx, r1 ; \
+	casa	[r1] ASI_N, r2, r3 ; \
+	cmp	r2, r3 ; \
+	bne	%icc, l2 ## b ; \
+	 mov	r3, r2 ; \
+	SET(ktr_buf, r3, r1) ; \
+	ldx	[r1], r1 ; \
+	mulx	r2, KTR_SIZEOF, r2 ; \
+	add	r1, r2, r1 ; \
+	rd	%tick, r2 ; \
+	stx	r2, [r1 + KTR_TIMESTAMP] ; \
+	lduw	[PCPU(CPUID)], r2 ; \
+	stw	r2, [r1 + KTR_CPU] ; \
+	stw	%g0, [r1 + KTR_LINE] ; \
+	stx	%g0, [r1 + KTR_FILE] ; \
+	SET(l1 ## b, r3, r2) ; \
+	stx	r2, [r1 + KTR_DESC]
+
+#define CATR(mask, desc, r1, r2, r3, l1, l2, l3) \
+	set	mask, r1 ; \
+	SET(ktr_mask, r3, r2) ; \
+	lduw	[r2], r2 ; \
+	and	r2, r1, r1 ; \
+	brz	r1, l3 ## f ; \
+	 nop ; \
+	lduw	[PCPU(CPUID)], r2 ; \
+	mov	_NCPUBITS, r3 ; \
+	udivx	r2, r3, r2 ; \
+	srl	r2, 0, r2 ; \
+	sllx	r2, PTR_SHIFT, r2 ; \
+	SET(ktr_cpumask, r3, r1) ; \
+	ldx	[r1 + r2], r1 ; \
+	lduw	[PCPU(CPUID)], r2 ; \
+	mov	_NCPUBITS, r3 ; \
+	udivx	r2, r3, r2 ; \
+	srl	r2, 0, r2 ; \
+	smul	r2, r3, r3 ; \
+	lduw	[PCPU(CPUID)], r2 ; \
+	sub	r2, r3, r3 ; \
+	mov	1, r2 ; \
+	sllx	r2, r3, r2 ; \
+	andn	r1, r2, r1 ; \
+	brz	r1, l3 ## f ; \
+	 nop ; \
+	ATR(desc, r1, r2, r3, l1, l2)
+
+#endif /* LOCORE */
+
+#endif /* !_MACHINE_KTR_H_ */


Property changes on: trunk/sys/sparc64/include/ktr.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/limits.h
===================================================================
--- trunk/sys/sparc64/include/limits.h	                        (rev 0)
+++ trunk/sys/sparc64/include/limits.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,42 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1988, 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.
+ *
+ * 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.
+ *
+ *	@(#)limits.h	8.3 (Berkeley) 1/4/94
+ * $FreeBSD: stable/10/sys/sparc64/include/limits.h 143140 2005-03-04 21:26:07Z joerg $
+ */
+
+#ifndef _MACHINE_LIMITS_H_
+#define	_MACHINE_LIMITS_H_
+
+#include <sys/cdefs.h>
+
+#if __CC_SUPPORTS_WARNING
+#warning "machine/limits.h is deprecated.  Include sys/limits.h instead."
+#endif
+
+#include <sys/limits.h>
+
+#endif /* !_MACHINE_LIMITS_H_ */


Property changes on: trunk/sys/sparc64/include/limits.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/lsu.h
===================================================================
--- trunk/sys/sparc64/include/lsu.h	                        (rev 0)
+++ trunk/sys/sparc64/include/lsu.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,87 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2001 by Thomas Moestl <tmm at 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, 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 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/lsu.h 206480 2010-04-11 15:35:17Z marius $
+ */
+
+#ifndef	_MACHINE_LSU_H_
+#define	_MACHINE_LSU_H_
+
+/*
+ * Definitions for the Load-Store-Unit Control Register. This is called
+ * Data Cache Unit Control Register (DCUCR) for UltraSPARC-III and greater.
+ */
+#define	LSU_IC		(1UL << 0)
+#define	LSU_DC		(1UL << 1)
+#define	LSU_IM		(1UL << 2)
+#define	LSU_DM		(1UL << 3)
+
+/* Parity control mask, UltraSPARC-I and II series only. */
+#define	LSU_FM_SHIFT	4
+#define	LSU_FM_BITS	16
+#define	LSU_FM_MASK	(((1UL << LSU_FM_BITS) - 1) << LSU_FM_SHIFT)
+
+#define	LSU_VM_SHIFT	25
+#define	LSU_VM_BITS	8
+#define	LSU_VM_MASK	(((1UL << LSU_VM_BITS) - 1) << LSU_VM_SHIFT)
+
+#define	LSU_PM_SHIFT	33
+#define	LSU_PM_BITS	8
+#define	LSU_PM_MASK	(((1UL << LSU_PM_BITS) - 1) << LSU_PM_SHIFT)
+
+#define	LSU_VW		(1UL << 21)
+#define	LSU_VR		(1UL << 22)
+#define	LSU_PW		(1UL << 23)
+#define	LSU_PR		(1UL << 24)
+
+/* The following bits are valid for the UltraSPARC-III series only. */
+#define	LSU_WE		(1UL << 41)
+#define	LSU_SL		(1UL << 42)
+#define	LSU_SPE		(1UL << 43)
+#define	LSU_HPE		(1UL << 44)
+#define	LSU_PE		(1UL << 45)
+#define	LSU_RE		(1UL << 46)
+#define	LSU_ME		(1UL << 47)
+#define	LSU_CV		(1UL << 48)
+#define	LSU_CP		(1UL << 49)
+
+/* The following bit is valid for the UltraSPARC-IV only. */
+#define	LSU_WIH		(1UL << 4)
+
+/* The following bits are valid for the UltraSPARC-IV+ only. */
+#define	LSU_PPS_SHIFT	50
+#define	LSU_PPS_BITS	2
+#define	LSU_PPS_MASK	(((1UL << LSU_PPS_BITS) - 1) << LSU_PPS_SHIFT)
+
+#define	LSU_IPS_SHIFT	52
+#define	LSU_IPS_BITS	2
+#define	LSU_IPS_MASK	(((1UL << LSU_IPS_BITS) - 1) << LSU_IPS_SHIFT)
+
+#define	LSU_PCM		(1UL << 54)
+#define	LSU_WCE		(1UL << 55)
+
+/* The following bit is valid for the SPARC64 V, VI, VII and VIIIfx only. */
+#define	LSU_WEAK_SPCA	(1UL << 41)
+
+#endif	/* _MACHINE_LSU_H_ */


Property changes on: trunk/sys/sparc64/include/lsu.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/mcntl.h
===================================================================
--- trunk/sys/sparc64/include/mcntl.h	                        (rev 0)
+++ trunk/sys/sparc64/include/mcntl.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,63 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Marius Strobl <marius at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/mcntl.h 207537 2010-05-02 19:38:17Z marius $
+ */
+
+#ifndef	_MACHINE_MCNTL_H
+#define	_MACHINE_MCNTL_H
+
+/*
+ * Definitions for the SPARC64 V, VI, VII and VIIIfx Memory Control Register
+ */
+#define	MCNTL_JPS1_TSBP		(1UL << 8)
+
+#define	MCNTL_RMD_SHIFT		12
+#define	MCNTL_RMD_BITS		2
+#define	MCNTL_RMD_MASK							\
+	(((1UL << MCNTL_RMD_BITS) - 1) << MCNTL_RMD_SHIFT)
+#define	MCNTL_RMD_FULL		(0UL << MCNTL_RMD_SHIFT)
+#define	MCNTL_RMD_1024		(2UL << MCNTL_RMD_SHIFT)
+#define	MCNTL_RMD_512		(3UL << MCNTL_RMD_SHIFT)
+
+#define	MCNTL_FW_FDTLB		(1UL << 14)
+#define	MCNTL_FW_FITLB		(1UL << 15)
+#define	MCNTL_NC_CACHE		(1UL << 16)
+
+/* The following bits are valid for the SPARC64 VI, VII and VIIIfx only. */
+#define	MCNTL_MPG_SDTLB		(1UL << 6)
+#define	MCNTL_MPG_SITLB		(1UL << 7)
+
+/* The following bits are valid for the SPARC64 VIIIfx only. */
+#define	MCNTL_HPF_SHIFT		18
+#define	MCNTL_HPF_BITS		2
+#define	MCNTL_HPF_MASK							\
+	(((1UL << MCNTL_HPF_BITS) - 1) << MCNTL_HPF_SHIFT)
+#define	MCNTL_HPF_STRONG	(0UL << MCNTL_HPF_SHIFT)
+#define	MCNTL_HPF_NOT		(1UL << MCNTL_HPF_SHIFT)
+#define	MCNTL_HPF_WEAK		(2UL << MCNTL_HPF_SHIFT)
+
+#endif	/* _MACHINE_MCNTL_H */


Property changes on: trunk/sys/sparc64/include/mcntl.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/md_var.h
===================================================================
--- trunk/sys/sparc64/include/md_var.h	                        (rev 0)
+++ trunk/sys/sparc64/include/md_var.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,79 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1995 Bruce D. Evans.
+ * 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. Neither the name of the author nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
+ *
+ *	from: FreeBSD: src/sys/i386/include/md_var.h,v 1.40 2001/07/12
+ * $FreeBSD: stable/10/sys/sparc64/include/md_var.h 292771 2015-12-27 14:39:47Z marius $
+ */
+
+#ifndef	_MACHINE_MD_VAR_H_
+#define	_MACHINE_MD_VAR_H_
+
+typedef void cpu_block_copy_t(const void *src, void *dst, size_t len);
+typedef void cpu_block_zero_t(void *dst, size_t len);
+
+extern	char	tl0_base[];
+extern	char	_end[];
+
+extern	long	Maxmem;
+
+extern	vm_offset_t kstack0;
+extern	vm_paddr_t kstack0_phys;
+
+struct	pcpu;
+struct	md_utrap;
+
+uint32_t cpu_get_mid(u_int cpu_impl);
+void	cpu_identify(u_long vers, u_int clock, u_int id);
+const char *cpu_portid_prop(u_int cpu_impl);
+void	cpu_setregs(struct pcpu *pc);
+int	is_physical_memory(vm_paddr_t addr);
+struct md_utrap *utrap_alloc(void);
+void	utrap_free(struct md_utrap *ut);
+struct md_utrap *utrap_hold(struct md_utrap *ut);
+
+cpu_block_copy_t spitfire_block_copy;
+cpu_block_zero_t spitfire_block_zero;
+cpu_block_copy_t zeus_block_copy;
+cpu_block_zero_t zeus_block_zero;
+
+extern	cpu_block_copy_t *cpu_block_copy;
+extern	cpu_block_zero_t *cpu_block_zero;
+
+/*
+ * Given that the VTOC8 disk label only uses 16-bit fields for cylinders,
+ * heads and sectors we might need to adjust the geometry of large disks.
+ */
+struct ccb_calc_geometry;
+int scsi_da_bios_params(struct ccb_calc_geometry *ccg);
+struct disk;
+void sparc64_ata_disk_firmware_geom_adjust(struct disk *disk);
+#define	ata_disk_firmware_geom_adjust(disk)				\
+	sparc64_ata_disk_firmware_geom_adjust(disk)
+
+#endif /* !_MACHINE_MD_VAR_H_ */


Property changes on: trunk/sys/sparc64/include/md_var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/memdev.h
===================================================================
--- trunk/sys/sparc64/include/memdev.h	                        (rev 0)
+++ trunk/sys/sparc64/include/memdev.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,41 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Mark R V Murray
+ * 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
+ *    in this position and unchanged.
+ * 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 AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/memdev.h 217515 2011-01-17 22:58:28Z jkim $
+ */
+
+#ifndef _MACHINE_MEMDEV_H_
+#define	_MACHINE_MEMDEV_H_
+
+#define	CDEV_MINOR_MEM	0
+#define	CDEV_MINOR_KMEM	1
+
+d_open_t	memopen;
+d_read_t	memrw;
+#define		memioctl	(d_ioctl_t *)NULL
+#define		memmmap		(d_mmap_t *)NULL
+
+#endif /* _MACHINE_MEMDEV_H_ */


Property changes on: trunk/sys/sparc64/include/memdev.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/metadata.h
===================================================================
--- trunk/sys/sparc64/include/metadata.h	                        (rev 0)
+++ trunk/sys/sparc64/include/metadata.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,46 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/metadata.h 139825 2005-01-07 02:29:27Z imp $
+ */
+
+#ifndef _MACHINE_METADATA_H_
+#define	_MACHINE_METADATA_H_
+
+#define	MODINFOMD_ENVP		0x1001
+#define	MODINFOMD_HOWTO		0x1002
+#define	MODINFOMD_KERNEND	0x1003
+#define	MODINFOMD_DTLB_SLOTS	0x1004
+#define	MODINFOMD_ITLB_SLOTS	0x1005
+#define	MODINFOMD_DTLB		0x1006
+#define	MODINFOMD_ITLB		0x1007
+
+struct tlb_entry {
+	vm_offset_t te_pa;
+	vm_offset_t te_va;
+};
+
+#endif /* !_MACHINE_METADATA_H_ */


Property changes on: trunk/sys/sparc64/include/metadata.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/nexusvar.h
===================================================================
--- trunk/sys/sparc64/include/nexusvar.h	                        (rev 0)
+++ trunk/sys/sparc64/include/nexusvar.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,35 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Marius Strobl <marius at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/nexusvar.h 203844 2010-02-13 18:51:49Z marius $
+ */
+
+#ifndef _MACHINE_NEXUSVAR_H_
+#define	_MACHINE_NEXUSVAR_H_
+
+DECLARE_CLASS(nexus_driver);
+
+#endif /* _MACHINE_NEXUSVAR_H_ */


Property changes on: trunk/sys/sparc64/include/nexusvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/ofw_machdep.h
===================================================================
--- trunk/sys/sparc64/include/ofw_machdep.h	                        (rev 0)
+++ trunk/sys/sparc64/include/ofw_machdep.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,46 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 by Thomas Moestl <tmm at 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, 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 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/ofw_machdep.h 230632 2012-01-27 22:35:53Z marius $
+ */
+
+#ifndef _MACHINE_OFW_MACHDEP_H_
+#define _MACHINE_OFW_MACHDEP_H_
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <dev/ofw/openfirm.h>
+
+typedef uint64_t cell_t;
+
+int  OF_decode_addr(phandle_t, int, int *, bus_addr_t *);
+void OF_getetheraddr(device_t, u_char *);
+u_int OF_getscsinitid(device_t);
+void OF_panic(const char *fmt, ...) __dead2 __printflike(1, 2);
+void cpu_shutdown(void *) __dead2;
+int  ofw_entry(void *);
+void ofw_exit(void *) __dead2;
+
+#endif /* _MACHINE_OFW_MACHDEP_H_ */


Property changes on: trunk/sys/sparc64/include/ofw_machdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/ofw_mem.h
===================================================================
--- trunk/sys/sparc64/include/ofw_mem.h	                        (rev 0)
+++ trunk/sys/sparc64/include/ofw_mem.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,47 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/ofw_mem.h 115971 2003-06-07 18:29:29Z jake $
+ */
+
+#ifndef _MACHINE_OFW_MEM_H_
+#define	_MACHINE_OFW_MEM_H_
+
+struct ofw_mem_region {
+	vm_paddr_t mr_start;
+	vm_size_t mr_size;
+};
+
+struct ofw_map {
+	vm_offset_t om_start;
+	vm_size_t om_size;
+	u_long	om_tte;
+};
+
+extern	struct ofw_mem_region sparc64_memreg[];
+extern	int sparc64_nmemreg;
+
+#endif


Property changes on: trunk/sys/sparc64/include/ofw_mem.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/ofw_nexus.h
===================================================================
--- trunk/sys/sparc64/include/ofw_nexus.h	                        (rev 0)
+++ trunk/sys/sparc64/include/ofw_nexus.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,80 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999 Matthew R. Green
+ * 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 ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1998, 1999 Eduardo E. Horvath
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: psychoreg.h,v 1.14 2008/05/30 02:29:37 mrg Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/ofw_nexus.h 219567 2011-03-12 14:33:32Z marius $
+ */
+
+#ifndef _MACHINE_OFW_NEXUS_H_
+#define	_MACHINE_OFW_NEXUS_H_
+
+/*
+ * These are the regs used for devices on the nexus. They apply to all of
+ * Fireplane/Safari, JBus and UPA.
+ */
+
+struct nexus_regs {
+	uint32_t	phys_hi;
+	uint32_t	phys_lo;
+	uint32_t	size_hi;
+	uint32_t	size_lo;
+};
+
+#define	NEXUS_REG_PHYS(r) \
+	(((uint64_t)(r)->phys_hi << 32) | (uint64_t)(r)->phys_lo)
+#define	NEXUS_REG_SIZE(r) \
+	(((uint64_t)(r)->size_hi << 32) | (uint64_t)(r)->size_lo)
+
+#endif /* !_MACHINE_OFW_NEXUS_H_ */


Property changes on: trunk/sys/sparc64/include/ofw_nexus.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/param.h
===================================================================
--- trunk/sys/sparc64/include/param.h	                        (rev 0)
+++ trunk/sys/sparc64/include/param.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,154 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: @(#)param.h	5.8 (Berkeley) 6/28/91
+ * $FreeBSD: stable/10/sys/sparc64/include/param.h 274648 2014-11-18 12:53:32Z kib $
+ */
+
+#ifndef _SPARC64_INCLUDE_PARAM_H_
+#define	_SPARC64_INCLUDE_PARAM_H_
+
+/*
+ * Machine dependent constants for sparc64.
+ */
+
+#include <machine/_align.h>
+
+#define __PCI_BAR_ZERO_VALID
+
+#ifndef MACHINE
+#define MACHINE		"sparc64"
+#endif
+#ifndef MACHINE_ARCH
+#define	MACHINE_ARCH	"sparc64"
+#endif
+#define MID_MACHINE	MID_SPARC64
+
+#if defined(SMP) || defined(KLD_MODULE)
+#ifndef MAXCPU
+#define MAXCPU		64
+#endif
+#else
+#define MAXCPU		1
+#endif /* SMP || KLD_MODULE */
+
+#ifndef MAXMEMDOM
+#define	MAXMEMDOM	1
+#endif
+
+#define	INT_SHIFT	2
+#define	PTR_SHIFT	3
+
+#define ALIGNBYTES	_ALIGNBYTES
+#define ALIGN(p)	_ALIGN(p)
+/*
+ * ALIGNED_POINTER is a boolean macro that checks whether an address
+ * is valid to fetch data elements of type t from on this architecture.
+ * This does not reflect the optimal alignment, just the possibility
+ * (within reasonable limits). 
+ */
+#define	ALIGNED_POINTER(p, t)	((((u_long)(p)) & (sizeof (t) - 1)) == 0)
+
+/*
+ * CACHE_LINE_SIZE is the compile-time maximum cache line size for an
+ * architecture.  It should be used with appropriate caution.
+ */
+#define	CACHE_LINE_SHIFT	7
+#define	CACHE_LINE_SIZE		(1 << CACHE_LINE_SHIFT)
+
+#define	PAGE_SHIFT_8K	13
+#define	PAGE_SIZE_8K	(1L<<PAGE_SHIFT_8K)
+#define	PAGE_MASK_8K	(PAGE_SIZE_8K-1)
+
+#define	PAGE_SHIFT_64K	16
+#define	PAGE_SIZE_64K	(1L<<PAGE_SHIFT_64K)
+#define	PAGE_MASK_64K	(PAGE_SIZE_64K-1)
+
+#define	PAGE_SHIFT_512K	19
+#define	PAGE_SIZE_512K	(1L<<PAGE_SHIFT_512K)
+#define	PAGE_MASK_512K	(PAGE_SIZE_512K-1)
+
+#define	PAGE_SHIFT_4M	22
+#define	PAGE_SIZE_4M	(1L<<PAGE_SHIFT_4M)
+#define	PAGE_MASK_4M	(PAGE_SIZE_4M-1)
+
+#define	PAGE_SHIFT_32M	25
+#define	PAGE_SIZE_32M	(1L<<PAGE_SHIFT_32M)
+#define	PAGE_MASK_32M	(PAGE_SIZE_32M-1)
+
+#define	PAGE_SHIFT_256M	28
+#define	PAGE_SIZE_256M	(1L<<PAGE_SHIFT_256M)
+#define	PAGE_MASK_256M	(PAGE_SIZE_256M-1)
+
+#define PAGE_SHIFT_MIN	PAGE_SHIFT_8K
+#define PAGE_SIZE_MIN	PAGE_SIZE_8K
+#define PAGE_MASK_MIN	PAGE_MASK_8K
+#define PAGE_SHIFT	PAGE_SHIFT_8K	/* LOG2(PAGE_SIZE) */
+#define PAGE_SIZE	PAGE_SIZE_8K	/* bytes/page */
+#define PAGE_MASK	PAGE_MASK_8K
+#define PAGE_SHIFT_MAX	PAGE_SHIFT_4M
+#define PAGE_SIZE_MAX	PAGE_SIZE_4M
+#define PAGE_MASK_MAX	PAGE_MASK_4M
+
+#define	MAXPAGESIZES	1		/* maximum number of supported page sizes */
+
+#ifndef KSTACK_PAGES
+#define KSTACK_PAGES		4	/* pages of kernel stack (with pcb) */
+#endif
+#define KSTACK_GUARD_PAGES	1	/* pages of kstack guard; 0 disables */
+#define PCPU_PAGES		1
+
+/*
+ * Ceiling on size of buffer cache (really only effects write queueing,
+ * the VM page cache is not effected), can be changed via
+ * the kern.maxbcache /boot/loader.conf variable.
+ */
+#ifndef VM_BCACHE_SIZE_MAX
+#define VM_BCACHE_SIZE_MAX      (400 * 1024 * 1024)
+#endif
+
+/*
+ * Mach derived conversion macros
+ */
+#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 sparc64_btop(x)		((unsigned long)(x) >> PAGE_SHIFT)
+#define sparc64_ptob(x)		((unsigned long)(x) << PAGE_SHIFT)
+
+#define	pgtok(x)		((unsigned long)(x) * (PAGE_SIZE / 1024))
+
+#ifdef _KERNEL
+#define	NO_FUEWORD	1
+#endif
+
+#endif /* !_SPARC64_INCLUDE_PARAM_H_ */


Property changes on: trunk/sys/sparc64/include/param.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/pcb.h
===================================================================
--- trunk/sys/sparc64/include/pcb.h	                        (rev 0)
+++ trunk/sys/sparc64/include/pcb.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,64 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/pcb.h 234785 2012-04-29 11:04:31Z dim $
+ */
+
+#ifndef	_MACHINE_PCB_H_
+#define	_MACHINE_PCB_H_
+
+#ifndef LOCORE
+#include <machine/frame.h>
+#endif
+
+#define	MAXWIN	8
+
+#define	PCB_FEF	(1 << 0)
+
+#ifndef LOCORE
+
+/* NOTE: pcb_ufp must be aligned on a 64 byte boundary. */
+struct pcb {
+	struct	rwindow pcb_rw[MAXWIN];
+	uint32_t pcb_kfp[64];
+	uint32_t pcb_ufp[64];
+	uint64_t pcb_rwsp[MAXWIN];
+	uint64_t pcb_flags;
+	uint64_t pcb_nsaved;
+	uint64_t pcb_pc;
+	uint64_t pcb_sp;
+	uint64_t pcb_tpc;
+	uint64_t pcb_pad[3];
+} __aligned(64);
+
+#ifdef _KERNEL
+void	makectx(struct trapframe *tf, struct pcb *pcb);
+int	savectx(struct pcb *pcb) __returns_twice;
+#endif
+
+#endif /* !LOCORE */
+
+#endif /* !_MACHINE_PCB_H_ */


Property changes on: trunk/sys/sparc64/include/pcb.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/pcpu.h
===================================================================
--- trunk/sys/sparc64/include/pcpu.h	                        (rev 0)
+++ trunk/sys/sparc64/include/pcpu.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,100 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999 Luoqi Chen <luoqi at 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, 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.
+ *
+ *	from: FreeBSD: src/sys/i386/include/globaldata.h,v 1.27 2001/04/27
+ * $FreeBSD: stable/10/sys/sparc64/include/pcpu.h 249265 2013-04-08 19:19:10Z glebius $
+ */
+
+#ifndef	_MACHINE_PCPU_H_
+#define	_MACHINE_PCPU_H_
+
+#include <machine/asmacros.h>
+#include <machine/cache.h>
+#include <machine/frame.h>
+#include <machine/intr_machdep.h>
+
+#define	ALT_STACK_SIZE	128
+
+struct pmap;
+
+/*
+ * Inside the kernel, the globally reserved register g7 is used to
+ * point at the globaldata structure.
+ */
+#define	PCPU_MD_FIELDS							\
+	struct	cacheinfo pc_cache;					\
+	struct	intr_request pc_irpool[IR_FREE];			\
+	struct	intr_request *pc_irhead;				\
+	struct	intr_request **pc_irtail;				\
+	struct	intr_request *pc_irfree;				\
+	struct	pmap *pc_pmap;						\
+	vm_offset_t pc_addr;						\
+	u_long	pc_tickref;						\
+	u_long	pc_tickadj;						\
+	u_long	pc_tickincrement;					\
+	u_int	pc_clock;						\
+	u_int	pc_impl;						\
+	u_int	pc_mid;							\
+	u_int	pc_node;						\
+	u_int	pc_tlb_ctx;						\
+	u_int	pc_tlb_ctx_max;						\
+	u_int	pc_tlb_ctx_min;						\
+	char	__pad[405]
+
+#ifdef _KERNEL
+
+extern void *dpcpu0;
+
+struct pcb;
+struct pcpu;
+
+register struct pcb *curpcb __asm__(__XSTRING(PCB_REG));
+register struct pcpu *pcpup __asm__(__XSTRING(PCPU_REG));
+
+#define	PCPU_GET(member)	(pcpup->pc_ ## member)
+
+static __inline __pure2 struct thread *
+__curthread(void)
+{
+	struct thread *td;
+
+	__asm("ldx [%" __XSTRING(PCPU_REG) "], %0" : "=r" (td));
+	return (td);
+}
+#define	curthread	(__curthread())
+
+/*
+ * XXX The implementation of this operation should be made atomic
+ * with respect to preemption.
+ */
+#define	PCPU_ADD(member, value)	(pcpup->pc_ ## member += (value))
+#define	PCPU_INC(member)	PCPU_ADD(member, 1)
+#define	PCPU_PTR(member)	(&pcpup->pc_ ## member)
+#define	PCPU_SET(member,value)	(pcpup->pc_ ## member = (value))
+
+#endif	/* _KERNEL */
+
+#endif	/* !_MACHINE_PCPU_H_ */


Property changes on: trunk/sys/sparc64/include/pcpu.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/pmap.h
===================================================================
--- trunk/sys/sparc64/include/pmap.h	                        (rev 0)
+++ trunk/sys/sparc64/include/pmap.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,130 @@
+/* $MidnightBSD$ */
+/*-
+ * 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 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.
+ * 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: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
+ *	from: @(#)pmap.h        7.4 (Berkeley) 5/12/91
+ *	from: FreeBSD: src/sys/i386/include/pmap.h,v 1.70 2000/11/30
+ * $FreeBSD: stable/10/sys/sparc64/include/pmap.h 253940 2013-08-04 21:17:05Z attilio $
+ */
+
+#ifndef	_MACHINE_PMAP_H_
+#define	_MACHINE_PMAP_H_
+
+#include <sys/queue.h>
+#include <sys/_cpuset.h>
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+#include <sys/_rwlock.h>
+#include <machine/cache.h>
+#include <machine/tte.h>
+
+#define	PMAP_CONTEXT_MAX	8192
+
+typedef	struct pmap *pmap_t;
+
+struct md_page {
+	TAILQ_HEAD(, tte) tte_list;
+	struct	pmap *pmap;
+	uint32_t colors[DCACHE_COLORS];
+	int32_t	color;
+};
+
+struct pmap {
+	struct	mtx pm_mtx;
+	struct	tte *pm_tsb;
+	vm_object_t pm_tsb_obj;
+	cpuset_t pm_active;
+	u_int	pm_context[MAXCPU];
+	struct	pmap_statistics pm_stats;
+};
+
+#define	PMAP_LOCK(pmap)		mtx_lock(&(pmap)->pm_mtx)
+#define	PMAP_LOCK_ASSERT(pmap, type)					\
+				mtx_assert(&(pmap)->pm_mtx, (type))
+#define	PMAP_LOCK_DESTROY(pmap)	mtx_destroy(&(pmap)->pm_mtx)
+#define	PMAP_LOCK_INIT(pmap)	mtx_init(&(pmap)->pm_mtx, "pmap",	\
+				    NULL, MTX_DEF | MTX_DUPOK)
+#define	PMAP_LOCKED(pmap)	mtx_owned(&(pmap)->pm_mtx)
+#define	PMAP_MTX(pmap)		(&(pmap)->pm_mtx)
+#define	PMAP_TRYLOCK(pmap)	mtx_trylock(&(pmap)->pm_mtx)
+#define	PMAP_UNLOCK(pmap)	mtx_unlock(&(pmap)->pm_mtx)
+
+#define	pmap_page_get_memattr(m)	VM_MEMATTR_DEFAULT
+#define	pmap_page_is_write_mapped(m)	(((m)->aflags & PGA_WRITEABLE) != 0)
+#define	pmap_page_set_memattr(m, ma)	(void)0
+
+void	pmap_bootstrap(u_int cpu_impl);
+vm_paddr_t pmap_kextract(vm_offset_t va);
+void	pmap_kenter(vm_offset_t va, vm_page_t m);
+void	pmap_kremove(vm_offset_t);
+void	pmap_kenter_flags(vm_offset_t va, vm_paddr_t pa, u_long flags);
+void	pmap_kremove_flags(vm_offset_t va);
+boolean_t pmap_page_is_mapped(vm_page_t m);
+
+int	pmap_cache_enter(vm_page_t m, vm_offset_t va);
+
+int	pmap_remove_tte(struct pmap *pm1, struct pmap *pm2, struct tte *tp,
+			vm_offset_t va);
+
+void	pmap_map_tsb(void);
+void	pmap_set_kctx(void);
+
+#define	vtophys(va)	pmap_kextract((vm_offset_t)(va))
+
+extern	struct pmap kernel_pmap_store;
+#define	kernel_pmap	(&kernel_pmap_store)
+extern	struct rwlock_padalign tte_list_global_lock;
+extern	vm_paddr_t phys_avail[];
+extern	vm_offset_t virtual_avail;
+extern	vm_offset_t virtual_end;
+
+#ifdef PMAP_STATS
+
+SYSCTL_DECL(_debug_pmap_stats);
+
+#define	PMAP_STATS_VAR(name) \
+	static long name; \
+	SYSCTL_LONG(_debug_pmap_stats, OID_AUTO, name, CTLFLAG_RW,	\
+	    &name, 0, "")
+
+#define	PMAP_STATS_INC(var) \
+	atomic_add_long(&var, 1)
+
+#else
+
+#define	PMAP_STATS_VAR(name)
+#define	PMAP_STATS_INC(var)
+
+#endif
+
+#endif /* !_MACHINE_PMAP_H_ */


Property changes on: trunk/sys/sparc64/include/pmap.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/pmc_mdep.h
===================================================================
--- trunk/sys/sparc64/include/pmc_mdep.h	                        (rev 0)
+++ trunk/sys/sparc64/include/pmc_mdep.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,29 @@
+/* $MidnightBSD$ */
+/*-
+ * This file is in the public domain.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/pmc_mdep.h 174405 2007-12-07 13:45:47Z jkoshy $
+ */
+
+#ifndef _MACHINE_PMC_MDEP_H_
+#define	_MACHINE_PMC_MDEP_H_
+
+union pmc_md_op_pmcallocate {
+	uint64_t		__pad[4];
+};
+
+/* Logging */
+#define	PMCLOG_READADDR		PMCLOG_READ64
+#define	PMCLOG_EMITADDR		PMCLOG_EMIT64
+
+#if	_KERNEL
+union pmc_md_pmc {
+};
+
+#define	PMC_TRAPFRAME_TO_PC(TF)	(0)	/* Stubs */
+#define	PMC_TRAPFRAME_TO_FP(TF)	(0)
+#define	PMC_TRAPFRAME_TO_SP(TF)	(0)
+
+#endif
+
+#endif /* !_MACHINE_PMC_MDEP_H_ */


Property changes on: trunk/sys/sparc64/include/pmc_mdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/proc.h
===================================================================
--- trunk/sys/sparc64/include/proc.h	                        (rev 0)
+++ trunk/sys/sparc64/include/proc.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,79 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1991 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.
+ * 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: @(#)proc.h        7.1 (Berkeley) 5/15/91
+ *	from: FreeBSD: src/sys/i386/include/proc.h,v 1.11 2001/06/29
+ * $FreeBSD: stable/10/sys/sparc64/include/proc.h 255937 2013-09-29 13:09:25Z marius $
+ */
+
+#ifndef	_MACHINE_PROC_H_
+#define	_MACHINE_PROC_H_
+
+#include <machine/utrap.h>
+
+struct md_utrap {
+	utrap_entry_t *ut_precise[UT_MAX];	/* must be first */
+	int	ut_refcnt;
+};
+
+struct mdthread {
+	int	md_spinlock_count;	/* (k) */
+	register_t md_saved_pil;	/* (k) */
+};
+
+struct mdproc {
+	struct	md_utrap *md_utrap;
+	void	*md_sigtramp;
+};
+
+#define	KINFO_PROC_SIZE 1088
+
+#ifdef _KERNEL
+
+#include <machine/pcb.h>
+
+/* Get the current kernel thread stack usage. */
+#define	GET_STACK_USAGE(total, used) do {				\
+	struct thread *td = curthread;					\
+	(total) = td->td_kstack_pages * PAGE_SIZE - sizeof(struct pcb);	\
+	(used) = (char *)td->td_kstack +				\
+	    td->td_kstack_pages * PAGE_SIZE -				\
+	    (char *)&td;						\
+} while (0)
+
+struct syscall_args {
+	u_int code;
+	struct sysent *callp;
+	register_t args[8];
+	int narg;
+};
+
+#endif
+
+#endif /* !_MACHINE_PROC_H_ */


Property changes on: trunk/sys/sparc64/include/proc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/profile.h
===================================================================
--- trunk/sys/sparc64/include/profile.h	                        (rev 0)
+++ trunk/sys/sparc64/include/profile.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,103 @@
+/* $MidnightBSD$ */
+/*-
+ * 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 at 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: NetBSD: profile.h,v 1.9 1997/04/06 08:47:37 cgd Exp
+ *	from: FreeBSD: src/sys/alpha/include/profile.h,v 1.4 1999/12/29
+ * $FreeBSD: stable/10/sys/sparc64/include/profile.h 169488 2007-05-11 23:43:55Z marius $
+ */
+
+#ifndef _MACHINE_PROFILE_H_
+#define	_MACHINE_PROFILE_H_
+
+#if !defined(_KERNEL) && !defined(_SYS_CDEFS_H_)
+#error this file needs sys/cdefs.h as a prerequisite
+#endif
+
+#define	FUNCTION_ALIGNMENT	32
+
+typedef u_long	fptrdiff_t;
+
+#ifdef _KERNEL
+
+#include <machine/cpufunc.h>
+#include <machine/intr_machdep.h>
+
+#define	_MCOUNT_DECL	void mcount
+#define	MCOUNT
+
+#define	MCOUNT_DECL(s)	register_t s;
+#define	MCOUNT_ENTER(s)	s = rdpr(pil); wrpr(pil, 0, PIL_TICK)
+#define	MCOUNT_EXIT(s)	wrpr(pil, 0, s)
+
+void bintr(void);
+void btrap(void);
+void eintr(void);
+void user(void);
+
+#define	MCOUNT_FROMPC_USER(pc)					\
+	((pc < (uintfptr_t)VM_MAXUSER_ADDRESS) ? (uintfptr_t)user : pc)
+
+#define	MCOUNT_FROMPC_INTR(pc)					\
+	((pc >= (uintfptr_t)btrap && pc < (uintfptr_t)eintr) ?	\
+	    ((pc >= (uintfptr_t)bintr) ? (uintfptr_t)bintr :	\
+		(uintfptr_t)btrap) : ~0UL)
+
+void	mcount(uintfptr_t frompc, uintfptr_t selfpc);
+
+#else /* !_KERNEL */
+
+typedef u_long	uintfptr_t;
+
+#define	_MCOUNT_DECL	static __inline void __mcount
+
+#ifdef __GNUCLIKE_ASM
+#define	MCOUNT								\
+void									\
+_mcount()								\
+{									\
+	uintfptr_t frompc, selfpc;					\
+									\
+	/*								\
+	 * Find the return address for mcount,				\
+	 * and the return address for mcount's caller.			\
+	 *								\
+	 * selfpc = pc pushed by call to mcount				\
+	 */								\
+	__asm("add %%o7, 8, %0" : "=r" (selfpc));			\
+	/*								\
+	 * frompc = pc pushed by call to mcount's caller.		\
+	 */								\
+	__asm("add %%i7, 8, %0" : "=r" (frompc));			\
+	__mcount(frompc, selfpc);					\
+}
+#else /* !__GNUCLIKE_ASM */
+#define	MCOUNT
+#endif /* __GNUCLIKE_ASM */
+
+#endif /* _KERNEL */
+
+#endif /* !_MACHINE_PROFILE_H_ */


Property changes on: trunk/sys/sparc64/include/profile.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/pstate.h
===================================================================
--- trunk/sys/sparc64/include/pstate.h	                        (rev 0)
+++ trunk/sys/sparc64/include/pstate.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,64 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/pstate.h 88626 2001-12-29 07:01:34Z jake $
+ */
+
+#ifndef	_MACHINE_PSTATE_H_
+#define	_MACHINE_PSTATE_H_
+
+#define	PSTATE_AG		(1<<0)
+#define	PSTATE_IE		(1<<1)
+#define	PSTATE_PRIV		(1<<2)
+#define	PSTATE_AM		(1<<3)
+#define	PSTATE_PEF		(1<<4)
+#define	PSTATE_RED		(1<<5)
+
+#define	PSTATE_MM_SHIFT		(6)
+#define	PSTATE_MM_SIZE		(2)
+#define	PSTATE_MM_MASK		(((1<<PSTATE_MM_SIZE)-1)<<PSTATE_MM_SHIFT)
+#define	PSTATE_MM_TSO		(0<<PSTATE_MM_SHIFT)
+#define	PSTATE_MM_PSO		(1<<PSTATE_MM_SHIFT)
+#define	PSTATE_MM_RMO		(2<<PSTATE_MM_SHIFT)
+
+#define	PSTATE_TLE		(1<<8)
+#define	PSTATE_CLE		(1<<9)
+#define	PSTATE_MG		(1<<10)
+#define	PSTATE_IG		(1<<11)
+
+#define	PSTATE_MM		PSTATE_MM_TSO
+
+#define	PSTATE_NORMAL		(PSTATE_MM | PSTATE_PEF | PSTATE_PRIV)
+#define	PSTATE_ALT		(PSTATE_NORMAL | PSTATE_AG)
+#define	PSTATE_INTR		(PSTATE_NORMAL | PSTATE_IG)
+#define	PSTATE_MMU		(PSTATE_NORMAL | PSTATE_MG)
+
+#define	PSTATE_KERNEL		(PSTATE_NORMAL | PSTATE_IE)
+
+#define	PSTATE_SECURE(pstate) \
+	(((pstate) & ~(PSTATE_AM|PSTATE_MM_MASK)) == (PSTATE_IE|PSTATE_PEF))
+
+#endif /* !_MACHINE_PSTATE_H_ */


Property changes on: trunk/sys/sparc64/include/pstate.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/ptrace.h
===================================================================
--- trunk/sys/sparc64/include/ptrace.h	                        (rev 0)
+++ trunk/sys/sparc64/include/ptrace.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,37 @@
+/* $MidnightBSD$ */
+/*-
+ * 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.
+ * 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
+ * $FreeBSD: stable/10/sys/sparc64/include/ptrace.h 139825 2005-01-07 02:29:27Z imp $
+ */
+
+#ifndef	_MACHINE_PTRACE_H_
+#define	_MACHINE_PTRACE_H_
+
+#endif


Property changes on: trunk/sys/sparc64/include/ptrace.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/reg.h
===================================================================
--- trunk/sys/sparc64/include/reg.h	                        (rev 0)
+++ trunk/sys/sparc64/include/reg.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,120 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 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: @(#)reg.h	5.5 (Berkeley) 1/18/91
+ *	from: FreeBSD: src/sys/i386/include/reg.h,v 1.23 2000/09/21
+ * $FreeBSD: stable/10/sys/sparc64/include/reg.h 283910 2015-06-02 14:54:53Z jhb $
+ */
+
+#ifndef	_MACHINE_REG_H_
+#define	_MACHINE_REG_H_
+
+/*
+ * Register set accessible via /proc/$pid/regs and PT_{SET,GET}REGS.
+ *
+ * NOTE: DO NOT CHANGE THESE STRUCTURES.  The offsets of the fields are
+ * hardcoded in gdb.  Changing them and recompiling doesn't help, the
+ * constants in nm-fbsd.h must also be updated.
+ */
+
+struct reg32 {
+	uint32_t r_global[8];
+	uint32_t r_out[8];
+	uint32_t r_npc;
+	uint32_t r_pc;
+	uint32_t r_psr;
+	uint32_t r_wim;
+	uint32_t r_pad[4];
+};
+
+struct reg {
+	uint64_t r_global[8];
+	uint64_t r_out[8];
+	uint64_t r_fprs;
+	uint64_t r_fsr;
+	uint64_t r_gsr;
+	uint64_t r_level;
+	uint64_t r_pil;
+	uint64_t r_sfar;
+	uint64_t r_sfsr;
+	uint64_t r_tar;
+	uint64_t r_tnpc;
+	uint64_t r_tpc;
+	uint64_t r_tstate;
+	uint64_t r_type;
+	uint64_t r_y;
+	uint64_t r_wstate;
+	uint64_t r_pad[2];
+};
+
+/*
+ * Register set accessible via /proc/$pid/fpregs.
+ */
+
+struct fpreg32 {
+	uint32_t fr_regs[32];
+	uint32_t fr_fsr;
+};
+
+struct fpreg {
+	uint32_t fr_regs[64];	/* our view is 64 32-bit registers */
+	int64_t	fr_fsr;		/* %fsr */
+	int32_t	fr_gsr;		/* %gsr */
+	int32_t fr_pad[1];
+};
+
+/*
+ * Register set accessible via /proc/$pid/dbregs.
+ */
+struct dbreg {
+	int dummy;
+};
+
+/*
+ * NB: sparcv8 binaries are not supported even though this header
+ * defines the relevant structures.
+ */
+#define	__HAVE_REG32
+
+#ifdef _KERNEL
+/*
+ * XXX these interfaces are MI, so they should be declared in a MI place.
+ */
+int	fill_regs(struct thread *, struct reg *);
+int	set_regs(struct thread *, struct reg *);
+int	fill_fpregs(struct thread *, struct fpreg *);
+int	set_fpregs(struct thread *, struct fpreg *);
+int	fill_dbregs(struct thread *, struct dbreg *);
+int	set_dbregs(struct thread *, struct dbreg *);
+#endif
+
+#endif /* !_MACHINE_REG_H_ */


Property changes on: trunk/sys/sparc64/include/reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/reloc.h
===================================================================
--- trunk/sys/sparc64/include/reloc.h	                        (rev 0)
+++ trunk/sys/sparc64/include/reloc.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,31 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1998 John Birrell <jb at cimlogic.com.au>.
+ * 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. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/reloc.h 165967 2007-01-12 07:26:21Z imp $
+ */


Property changes on: trunk/sys/sparc64/include/reloc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/resource.h
===================================================================
--- trunk/sys/sparc64/include/resource.h	                        (rev 0)
+++ trunk/sys/sparc64/include/resource.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,46 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 1998 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/resource.h 139825 2005-01-07 02:29:27Z imp $
+ */
+
+#ifndef _MACHINE_RESOURCE_H_
+#define	_MACHINE_RESOURCE_H_	1
+
+/*
+ * Definitions of resource types for Intel Architecture machines
+ * with support for legacy ISA devices and drivers.
+ */
+
+#define	SYS_RES_IRQ	1	/* interrupt lines */
+#define	SYS_RES_DRQ	2	/* isa dma lines */
+#define	SYS_RES_MEMORY	3	/* i/o memory */
+#define	SYS_RES_IOPORT	4	/* i/o ports */
+
+#endif /* !_MACHINE_RESOURCE_H_ */


Property changes on: trunk/sys/sparc64/include/resource.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/runq.h
===================================================================
--- trunk/sys/sparc64/include/runq.h	                        (rev 0)
+++ trunk/sys/sparc64/include/runq.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,59 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder <jake at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/runq.h 139825 2005-01-07 02:29:27Z imp $
+ */
+
+#ifndef	_MACHINE_RUNQ_H_
+#define	_MACHINE_RUNQ_H_
+
+#define	RQB_LEN		(1UL)		/* Number of priority status words. */
+#define	RQB_L2BPW	(6UL)		/* Log2(sizeof(rqb_word_t) * NBBY)). */
+#define	RQB_BPW		(1UL<<RQB_L2BPW)	/* Bits in an rqb_word_t. */
+
+#define	RQB_BIT(pri)	(1UL << ((pri) & (RQB_BPW - 1)))
+#define	RQB_WORD(pri)	((pri) >> RQB_L2BPW)
+
+#define	RQB_FFS(word)	(ffs64(word) - 1)
+
+/*
+ * Type of run queue status word.
+ */
+typedef	u_int64_t	rqb_word_t;
+
+static __inline u_long
+ffs64(u_long mask)
+{
+	u_long bit;
+
+	if (mask == 0)
+		return (0);
+	for (bit = 1; (mask & 1UL) == 0; bit++)
+		mask >>= 1UL;
+	return (bit);
+}
+
+#endif


Property changes on: trunk/sys/sparc64/include/runq.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/sc_machdep.h
===================================================================
--- trunk/sys/sparc64/include/sc_machdep.h	                        (rev 0)
+++ trunk/sys/sparc64/include/sc_machdep.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,77 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/sc_machdep.h 119380 2003-08-24 00:47:40Z jake $
+ */
+
+#ifndef	_MACHINE_SC_MACHDEP_H_
+#define	_MACHINE_SC_MACHDEP_H_
+
+/* Color attributes for foreground text */
+
+#define	FG_BLACK		0x0
+#define	FG_BLUE			0x1
+#define	FG_GREEN		0x2
+#define	FG_CYAN			0x3
+#define	FG_RED			0x4
+#define	FG_MAGENTA		0x5
+#define	FG_BROWN		0x6
+#define	FG_LIGHTGREY		0x7
+#define	FG_DARKGREY		0x8
+#define	FG_LIGHTBLUE		0x9
+#define	FG_LIGHTGREEN		0xa
+#define	FG_LIGHTCYAN		0xb
+#define	FG_LIGHTRED		0xc
+#define	FG_LIGHTMAGENTA		0xd
+#define	FG_YELLOW		0xe
+#define	FG_WHITE		0xf
+#define	FG_BLINK		0x80
+
+/* Color attributes for text background */
+
+#define	BG_BLACK		0x00
+#define	BG_BLUE			0x10
+#define	BG_GREEN		0x20
+#define	BG_CYAN			0x30
+#define	BG_RED			0x40
+#define	BG_MAGENTA		0x50
+#define	BG_BROWN		0x60
+#define	BG_LIGHTGREY		0x70
+#define	BG_DARKGREY		0x80
+#define	BG_LIGHTBLUE		0x90
+#define	BG_LIGHTGREEN		0xa0
+#define	BG_LIGHTCYAN		0xb0
+#define	BG_LIGHTRED		0xc0
+#define	BG_LIGHTMAGENTA		0xd0
+#define	BG_YELLOW		0xe0
+#define	BG_WHITE		0xf0
+
+#define	SC_NORM_ATTR		(FG_BLACK | BG_WHITE)
+#define	SC_NORM_REV_ATTR	(FG_WHITE | BG_BLACK)
+#define	SC_KERNEL_CONS_ATTR	(FG_BLACK | BG_WHITE)
+#define	SC_KERNEL_CONS_REV_ATTR	(FG_WHITE | BG_BLACK)
+
+#endif /* !_MACHINE_SC_MACHDEP_H_ */


Property changes on: trunk/sys/sparc64/include/sc_machdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/setjmp.h
===================================================================
--- trunk/sys/sparc64/include/setjmp.h	                        (rev 0)
+++ trunk/sys/sparc64/include/setjmp.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,58 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1998 John Birrell <jb at cimlogic.com.au>.
+ * 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. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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: FreeBSD: src/sys/i386/include/setjmp.h,v 1.5 2000/10/06
+ * $FreeBSD: stable/10/sys/sparc64/include/setjmp.h 165967 2007-01-12 07:26:21Z imp $
+ */
+
+#ifndef	_MACHINE_SETJMP_H_
+#define	_MACHINE_SETJMP_H_
+
+#include <sys/cdefs.h>
+
+#define	_JBLEN		5
+
+#define	_JB_FP		0
+#define	_JB_PC		1
+#define	_JB_SP		2
+#define	_JB_SIGMASK	3
+#define	_JB_SIGFLAG	5
+
+/*
+ * jmp_buf and sigjmp_buf are encapsulated in different structs to force
+ * compile-time diagnostics for mismatches.  The structs are the same
+ * internally to avoid some run-time errors for mismatches.
+ */
+#if __BSD_VISIBLE || __POSIX_VISIBLE || __XSI_VISIBLE
+typedef	struct _sigjmp_buf { long _sjb[_JBLEN + 1]; } sigjmp_buf[1];
+#endif
+
+typedef	struct _jmp_buf { long _jb[_JBLEN + 1]; } jmp_buf[1];
+
+#endif /* !_MACHINE_SETJMP_H_ */


Property changes on: trunk/sys/sparc64/include/setjmp.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/sf_buf.h
===================================================================
--- trunk/sys/sparc64/include/sf_buf.h	                        (rev 0)
+++ trunk/sys/sparc64/include/sf_buf.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,60 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Alan L. Cox <alc at cs.rice.edu>
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/sf_buf.h 255318 2013-09-06 17:44:13Z glebius $
+ */
+
+#ifndef _MACHINE_SF_BUF_H_
+#define _MACHINE_SF_BUF_H_
+
+#include <sys/queue.h>
+
+struct vm_page;
+
+struct sf_buf {
+	SLIST_ENTRY(sf_buf) free_list;	/* list of free buffer slots */
+	struct		vm_page *m;	/* currently mapped page */
+	vm_offset_t	kva;		/* va of mapping */
+};
+
+struct sf_buf * sf_buf_alloc(struct vm_page *m, int flags);
+void sf_buf_free(struct sf_buf *sf);
+
+static __inline vm_offset_t
+sf_buf_kva(struct sf_buf *sf)
+{
+
+	return (sf->kva);
+}
+
+static __inline struct vm_page *
+sf_buf_page(struct sf_buf *sf)
+{
+
+	return (sf->m);
+}
+
+#endif /* !_MACHINE_SF_BUF_H_ */


Property changes on: trunk/sys/sparc64/include/sf_buf.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/sigframe.h
===================================================================
--- trunk/sys/sparc64/include/sigframe.h	                        (rev 0)
+++ trunk/sys/sparc64/include/sigframe.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,41 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999 Marcel Moolenaar
+ * 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 
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *	from:	FreeBSD: src/sys/alpha/include/sigframe.h,v 1.1 1999/09/29
+ * $FreeBSD: stable/10/sys/sparc64/include/sigframe.h 82902 2001-09-03 22:41:40Z jake $
+ */
+
+#ifndef _MACHINE_SIGFRAME_H_
+#define _MACHINE_SIGFRAME_H_ 1
+
+struct sigframe {
+	ucontext_t	sf_uc;
+	siginfo_t	sf_si;
+};
+
+#endif /* _MACHINE_SIGFRAME_H_ */


Property changes on: trunk/sys/sparc64/include/sigframe.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/signal.h
===================================================================
--- trunk/sys/sparc64/include/signal.h	                        (rev 0)
+++ trunk/sys/sparc64/include/signal.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,48 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1986, 1989, 1991, 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.
+ * 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.
+ *
+ *      @(#)signal.h    8.1 (Berkeley) 6/11/93
+ * 	from: FreeBSD: src/sys/i386/include/signal.h,v 1.13 2000/11/09
+ * $FreeBSD: stable/10/sys/sparc64/include/signal.h 149337 2005-08-20 16:44:41Z stefanf $
+ */
+
+#ifndef	_MACHINE_SIGNAL_H_
+#define	_MACHINE_SIGNAL_H_
+
+#include <sys/cdefs.h>
+
+typedef	long sig_atomic_t;
+
+#if __BSD_VISIBLE
+struct sigcontext {
+	int	_dummy;
+};
+#endif /* __BSD_VISIBLE */
+
+#endif /* !_MACHINE_SIGNAL_H_ */


Property changes on: trunk/sys/sparc64/include/signal.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/smp.h
===================================================================
--- trunk/sys/sparc64/include/smp.h	                        (rev 0)
+++ trunk/sys/sparc64/include/smp.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,403 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * Copyright (c) 2007 - 2011 Marius Strobl <marius at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/smp.h 292787 2015-12-27 17:58:58Z marius $
+ */
+
+#ifndef	_MACHINE_SMP_H_
+#define	_MACHINE_SMP_H_
+
+#ifdef SMP
+
+#define	CPU_TICKSYNC		1
+#define	CPU_STICKSYNC		2
+#define	CPU_INIT		3
+#define	CPU_BOOTSTRAP		4
+
+#ifndef	LOCORE
+
+#include <sys/param.h>
+#include <sys/cpuset.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
+#include <sys/smp.h>
+
+#include <machine/atomic.h>
+#include <machine/intr_machdep.h>
+#include <machine/tte.h>
+
+#define	IDR_BUSY			0x0000000000000001ULL
+#define	IDR_NACK			0x0000000000000002ULL
+#define	IDR_CHEETAH_ALL_BUSY		0x5555555555555555ULL
+#define	IDR_CHEETAH_ALL_NACK		(~IDR_CHEETAH_ALL_BUSY)
+#define	IDR_CHEETAH_MAX_BN_PAIRS	32
+#define	IDR_JALAPENO_MAX_BN_PAIRS	4
+
+#define	IDC_ITID_SHIFT			14
+#define	IDC_BN_SHIFT			24
+
+#define	IPI_AST		PIL_AST
+#define	IPI_RENDEZVOUS	PIL_RENDEZVOUS
+#define	IPI_PREEMPT	PIL_PREEMPT
+#define	IPI_HARDCLOCK	PIL_HARDCLOCK
+#define	IPI_STOP	PIL_STOP
+#define	IPI_STOP_HARD	PIL_STOP
+
+#define	IPI_RETRIES	5000
+
+struct cpu_start_args {
+	u_int	csa_count;
+	u_int	csa_mid;
+	u_int	csa_state;
+	vm_offset_t csa_pcpu;
+	u_long	csa_tick;
+	u_long	csa_stick;
+	u_long	csa_ver;
+	struct	tte csa_ttes[PCPU_PAGES];
+};
+
+struct ipi_cache_args {
+	cpuset_t ica_mask;
+	vm_paddr_t ica_pa;
+};
+
+struct ipi_rd_args {
+	cpuset_t ira_mask;
+	register_t *ira_val;
+};
+
+struct ipi_tlb_args {
+	cpuset_t ita_mask;
+	struct	pmap *ita_pmap;
+	u_long	ita_start;
+	u_long	ita_end;
+};
+#define	ita_va	ita_start
+
+struct pcb;
+struct pcpu;
+
+extern struct pcb stoppcbs[];
+
+void	cpu_mp_bootstrap(struct pcpu *pc);
+void	cpu_mp_shutdown(void);
+
+typedef	void cpu_ipi_selected_t(cpuset_t, u_long, u_long, u_long);
+extern	cpu_ipi_selected_t *cpu_ipi_selected;
+typedef	void cpu_ipi_single_t(u_int, u_long, u_long, u_long);
+extern	cpu_ipi_single_t *cpu_ipi_single;
+
+void	mp_init(void);
+
+extern	struct mtx ipi_mtx;
+extern	struct ipi_cache_args ipi_cache_args;
+extern	struct ipi_rd_args ipi_rd_args;
+extern	struct ipi_tlb_args ipi_tlb_args;
+
+extern	char *mp_tramp_code;
+extern	u_long mp_tramp_code_len;
+extern	u_long mp_tramp_tlb_slots;
+extern	u_long mp_tramp_func;
+
+extern	void mp_startup(void);
+
+extern	char tl_ipi_cheetah_dcache_page_inval[];
+extern	char tl_ipi_spitfire_dcache_page_inval[];
+extern	char tl_ipi_spitfire_icache_page_inval[];
+
+extern	char tl_ipi_level[];
+
+extern	char tl_ipi_stick_rd[];
+extern	char tl_ipi_tick_rd[];
+
+extern	char tl_ipi_tlb_context_demap[];
+extern	char tl_ipi_tlb_page_demap[];
+extern	char tl_ipi_tlb_range_demap[];
+
+static __inline void
+ipi_all_but_self(u_int ipi)
+{
+	cpuset_t cpus;
+
+	if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
+		return;
+	cpus = all_cpus;
+	sched_pin();
+	CPU_CLR(PCPU_GET(cpuid), &cpus);
+	mtx_lock_spin(&ipi_mtx);
+	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi);
+	mtx_unlock_spin(&ipi_mtx);
+	sched_unpin();
+}
+
+static __inline void
+ipi_selected(cpuset_t cpus, u_int ipi)
+{
+
+	if (__predict_false(atomic_load_acq_int(&smp_started) == 0 ||
+	    CPU_EMPTY(&cpus)))
+		return;
+	mtx_lock_spin(&ipi_mtx);
+	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi);
+	mtx_unlock_spin(&ipi_mtx);
+}
+
+static __inline void
+ipi_cpu(int cpu, u_int ipi)
+{
+
+	if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
+		return;
+	mtx_lock_spin(&ipi_mtx);
+	cpu_ipi_single(cpu, 0, (u_long)tl_ipi_level, ipi);
+	mtx_unlock_spin(&ipi_mtx);
+}
+
+#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_)
+
+static __inline void *
+ipi_dcache_page_inval(void *func, vm_paddr_t pa)
+{
+	struct ipi_cache_args *ica;
+
+	if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
+		return (NULL);
+	sched_pin();
+	ica = &ipi_cache_args;
+	mtx_lock_spin(&ipi_mtx);
+	ica->ica_mask = all_cpus;
+	CPU_CLR(PCPU_GET(cpuid), &ica->ica_mask);
+	ica->ica_pa = pa;
+	cpu_ipi_selected(ica->ica_mask, 0, (u_long)func, (u_long)ica);
+	return (&ica->ica_mask);
+}
+
+static __inline void *
+ipi_icache_page_inval(void *func, vm_paddr_t pa)
+{
+	struct ipi_cache_args *ica;
+
+	if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
+		return (NULL);
+	sched_pin();
+	ica = &ipi_cache_args;
+	mtx_lock_spin(&ipi_mtx);
+	ica->ica_mask = all_cpus;
+	CPU_CLR(PCPU_GET(cpuid), &ica->ica_mask);
+	ica->ica_pa = pa;
+	cpu_ipi_selected(ica->ica_mask, 0, (u_long)func, (u_long)ica);
+	return (&ica->ica_mask);
+}
+
+static __inline void *
+ipi_rd(u_int cpu, void *func, u_long *val)
+{
+	struct ipi_rd_args *ira;
+
+	if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
+		return (NULL);
+	sched_pin();
+	ira = &ipi_rd_args;
+	mtx_lock_spin(&ipi_mtx);
+	CPU_SETOF(cpu, &ira->ira_mask);
+	ira->ira_val = val;
+	cpu_ipi_single(cpu, 0, (u_long)func, (u_long)ira);
+	return (&ira->ira_mask);
+}
+
+static __inline void *
+ipi_tlb_context_demap(struct pmap *pm)
+{
+	struct ipi_tlb_args *ita;
+	cpuset_t cpus;
+
+	if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
+		return (NULL);
+	sched_pin();
+	cpus = pm->pm_active;
+	CPU_AND(&cpus, &all_cpus);
+	CPU_CLR(PCPU_GET(cpuid), &cpus);
+	if (CPU_EMPTY(&cpus)) {
+		sched_unpin();
+		return (NULL);
+	}
+	ita = &ipi_tlb_args;
+	mtx_lock_spin(&ipi_mtx);
+	ita->ita_mask = cpus;
+	ita->ita_pmap = pm;
+	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap,
+	    (u_long)ita);
+	return (&ita->ita_mask);
+}
+
+static __inline void *
+ipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
+{
+	struct ipi_tlb_args *ita;
+	cpuset_t cpus;
+
+	if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
+		return (NULL);
+	sched_pin();
+	cpus = pm->pm_active;
+	CPU_AND(&cpus, &all_cpus);
+	CPU_CLR(PCPU_GET(cpuid), &cpus);
+	if (CPU_EMPTY(&cpus)) {
+		sched_unpin();
+		return (NULL);
+	}
+	ita = &ipi_tlb_args;
+	mtx_lock_spin(&ipi_mtx);
+	ita->ita_mask = cpus;
+	ita->ita_pmap = pm;
+	ita->ita_va = va;
+	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita);
+	return (&ita->ita_mask);
+}
+
+static __inline void *
+ipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
+{
+	struct ipi_tlb_args *ita;
+	cpuset_t cpus;
+
+	if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
+		return (NULL);
+	sched_pin();
+	cpus = pm->pm_active;
+	CPU_AND(&cpus, &all_cpus);
+	CPU_CLR(PCPU_GET(cpuid), &cpus);
+	if (CPU_EMPTY(&cpus)) {
+		sched_unpin();
+		return (NULL);
+	}
+	ita = &ipi_tlb_args;
+	mtx_lock_spin(&ipi_mtx);
+	ita->ita_mask = cpus;
+	ita->ita_pmap = pm;
+	ita->ita_start = start;
+	ita->ita_end = end;
+	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap,
+	    (u_long)ita);
+	return (&ita->ita_mask);
+}
+
+static __inline void
+ipi_wait(void *cookie)
+{
+	volatile cpuset_t *mask;
+
+	if (__predict_false((mask = cookie) != NULL)) {
+		while (!CPU_EMPTY(mask))
+			;
+		mtx_unlock_spin(&ipi_mtx);
+		sched_unpin();
+	}
+}
+
+#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */
+
+#endif /* !LOCORE */
+
+#else
+
+#ifndef	LOCORE
+
+static __inline void *
+ipi_dcache_page_inval(void *func __unused, vm_paddr_t pa __unused)
+{
+
+	return (NULL);
+}
+
+static __inline void *
+ipi_icache_page_inval(void *func __unused, vm_paddr_t pa __unused)
+{
+
+	return (NULL);
+}
+
+static __inline void *
+ipi_rd(u_int cpu __unused, void *func __unused, u_long *val __unused)
+{
+
+	return (NULL);
+}
+
+static __inline void *
+ipi_tlb_context_demap(struct pmap *pm __unused)
+{
+
+	return (NULL);
+}
+
+static __inline void *
+ipi_tlb_page_demap(struct pmap *pm __unused, vm_offset_t va __unused)
+{
+
+	return (NULL);
+}
+
+static __inline void *
+ipi_tlb_range_demap(struct pmap *pm __unused, vm_offset_t start __unused,
+    __unused vm_offset_t end)
+{
+
+	return (NULL);
+}
+
+static __inline void
+ipi_wait(void *cookie __unused)
+{
+
+}
+
+static __inline void
+tl_ipi_cheetah_dcache_page_inval(void)
+{
+
+}
+
+static __inline void
+tl_ipi_spitfire_dcache_page_inval(void)
+{
+
+}
+
+static __inline void
+tl_ipi_spitfire_icache_page_inval(void)
+{
+
+}
+
+#endif /* !LOCORE */
+
+#endif /* SMP */
+
+#endif /* !_MACHINE_SMP_H_ */


Property changes on: trunk/sys/sparc64/include/smp.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/stack.h
===================================================================
--- trunk/sys/sparc64/include/stack.h	                        (rev 0)
+++ trunk/sys/sparc64/include/stack.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,41 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/stack.h 174195 2007-12-02 20:40:35Z rwatson $
+ */
+
+#ifndef _MACHINE_STACK_H_
+#define	_MACHINE_STACK_H_
+
+extern char tl_trap_begin[];
+extern char tl_trap_end[];
+extern char tl_text_begin[];
+extern char tl_text_end[];
+
+#define	INKERNEL(va) \
+	((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS)
+
+#endif /* !_MACHINE_STACK_H_ */


Property changes on: trunk/sys/sparc64/include/stack.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/stdarg.h
===================================================================
--- trunk/sys/sparc64/include/stdarg.h	                        (rev 0)
+++ trunk/sys/sparc64/include/stdarg.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,102 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 David E. O'Brien.  All rights reserved.
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)stdarg.h	8.2 (Berkeley) 9/27/93
+ *	$NetBSD: stdarg.h,v 1.11 2000/07/23 21:36:56 mycroft Exp $
+ * $FreeBSD: stable/10/sys/sparc64/include/stdarg.h 162487 2006-09-21 01:37:02Z kan $
+ */
+
+#ifndef _MACHINE_STDARG_H_
+#define	_MACHINE_STDARG_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _VA_LIST_DECLARED
+#define	_VA_LIST_DECLARED
+typedef	__va_list	va_list;
+#endif
+
+#ifdef __GNUCLIKE_BUILTIN_STDARG
+
+#define	va_start(ap, last) \
+	__builtin_va_start((ap), (last))
+
+#define	va_arg(ap, type) \
+	__builtin_va_arg((ap), type)
+
+#if __ISO_C_VISIBLE >= 1999
+#define	va_copy(dest, src) \
+	__builtin_va_copy((dest), (src))
+#endif
+
+#define	va_end(ap) \
+	__builtin_va_end(ap)
+
+#else	/* ! __GNUCLIKE_BUILTIN_STDARG */
+
+#if !defined(__GNUCLIKE_BUILTIN_NEXT_ARG) && !defined(lint)
+#error no support for your compiler
+#endif
+
+#define	va_start(ap, last) \
+	(__builtin_next_arg(last), (ap) = (va_list)__builtin_saveregs())
+
+#define va_end(ap)	
+
+#define	__va_arg8(ap, type) \
+	(*(type *)(void *)((ap) += 8, (ap) - 8))
+#define	__va_arg16(ap, type) \
+	(*(type *)(void *)((ap) = (va_list)(((unsigned long)(ap) + 31) & -16),\
+			   (ap) - 16))
+#define	__va_int(ap, type) \
+	(*(type *)(void *)((ap) += 8, (ap) - sizeof(type)))
+
+#define	__REAL_TYPE_CLASS	8
+#define	__RECORD_TYPE_CLASS	12
+#define va_arg(ap, type) \
+	(__builtin_classify_type(*(type *)0) == __REAL_TYPE_CLASS ?	\
+	 (__alignof__(type) == 16 ? __va_arg16(ap, type) :		\
+	  __va_arg8(ap, type)) :					\
+	 (__builtin_classify_type(*(type *)0) < __RECORD_TYPE_CLASS ?	\
+	  __va_int(ap, type) :						\
+	  (sizeof(type) <= 8 ? __va_arg8(ap, type) :			\
+	   (sizeof(type) <= 16 ? __va_arg16(ap, type) :			\
+	    *__va_arg8(ap, type *)))))
+
+#endif /* __GNUCLIKE_BUILTIN_STDARG */
+
+#endif /* !_MACHINE_STDARG_H_ */


Property changes on: trunk/sys/sparc64/include/stdarg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/sysarch.h
===================================================================
--- trunk/sys/sparc64/include/sysarch.h	                        (rev 0)
+++ trunk/sys/sparc64/include/sysarch.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,75 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 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.
+ * 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: FreeBSD: src/sys/i386/include/sysarch.h,v 1.14 2000/09/21
+ * $FreeBSD: stable/10/sys/sparc64/include/sysarch.h 178445 2008-04-23 20:38:37Z marius $
+ */
+
+/*
+ * Architecture specific syscalls (sparc64)
+ */
+#ifndef _MACHINE_SYSARCH_H_
+#define _MACHINE_SYSARCH_H_
+
+#include <machine/utrap.h>
+
+#define	SPARC_UTRAP_INSTALL	1
+#define	SPARC_SIGTRAMP_INSTALL	2
+
+struct sparc_utrap_install_args {
+	int num;
+	const struct sparc_utrap_args *handlers;
+};
+
+struct sparc_sigtramp_install_args {
+	void	*sia_new;
+	void	**sia_old;
+};
+
+struct sparc_utrap_args {
+	utrap_entry_t type;
+	utrap_handler_t new_precise;
+	utrap_handler_t new_deferred;
+	utrap_handler_t *old_precise;
+	utrap_handler_t *old_deferred;
+};
+
+#ifndef _KERNEL
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int	__sparc_utrap_install(utrap_entry_t _type,
+	    utrap_handler_t _new_precise, utrap_handler_t _new_deferred,
+	    utrap_handler_t *_old_precise, utrap_handler_t *_old_deferred);
+int	sysarch(int _number, void *_args);
+__END_DECLS
+
+#endif
+
+#endif /* !_MACHINE_SYSARCH_H_ */


Property changes on: trunk/sys/sparc64/include/sysarch.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/tick.h
===================================================================
--- trunk/sys/sparc64/include/tick.h	                        (rev 0)
+++ trunk/sys/sparc64/include/tick.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,38 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/tick.h 214071 2010-10-19 19:44:05Z marius $
+ */
+
+#ifndef _MACHINE_TICK_H_
+#define	_MACHINE_TICK_H_
+
+extern u_int tick_et_use_stick;
+
+void	tick_clear(u_int cpu_impl);
+void	tick_stop(u_int cpu_impl);
+
+#endif


Property changes on: trunk/sys/sparc64/include/tick.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/tlb.h
===================================================================
--- trunk/sys/sparc64/include/tlb.h	                        (rev 0)
+++ trunk/sys/sparc64/include/tlb.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,176 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * Copyright (c) 2008, 2010 Marius Strobl <marius at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/tlb.h 223719 2011-07-02 11:14:54Z marius $
+ */
+
+#ifndef	_MACHINE_TLB_H_
+#define	_MACHINE_TLB_H_
+
+#define	TLB_DIRECT_ADDRESS_BITS		(43)
+#define	TLB_DIRECT_PAGE_BITS		(PAGE_SHIFT_4M)
+
+#define	TLB_DIRECT_ADDRESS_MASK		((1UL << TLB_DIRECT_ADDRESS_BITS) - 1)
+#define	TLB_DIRECT_PAGE_MASK		((1UL << TLB_DIRECT_PAGE_BITS) - 1)
+
+#define	TLB_PHYS_TO_DIRECT(pa)						\
+	((pa) | VM_MIN_DIRECT_ADDRESS)
+#define	TLB_DIRECT_TO_PHYS(va)						\
+	((va) & TLB_DIRECT_ADDRESS_MASK)
+#define	TLB_DIRECT_TO_TTE_MASK						\
+	(TD_V | TD_4M | (TLB_DIRECT_ADDRESS_MASK - TLB_DIRECT_PAGE_MASK))
+
+#define	TLB_DAR_SLOT_SHIFT		(3)
+#define	TLB_DAR_TLB_SHIFT		(16)
+#define	TLB_DAR_SLOT(tlb, slot)						\
+	((tlb) << TLB_DAR_TLB_SHIFT | (slot) << TLB_DAR_SLOT_SHIFT)
+#define	TLB_DAR_T16			(0)	/* US-III{,i,+}, IV{,+} */
+#define	TLB_DAR_T32			(0)	/* US-I, II{,e,i} */
+#define	TLB_DAR_DT512_0			(2)	/* US-III{,i,+}, IV{,+} */
+#define	TLB_DAR_DT512_1			(3)	/* US-III{,i,+}, IV{,+} */
+#define	TLB_DAR_IT128			(2)	/* US-III{,i,+}, IV */
+#define	TLB_DAR_IT512			(2)	/* US-IV+ */
+#define	TLB_DAR_FTLB			(0)	/* SPARC64 V, VI, VII, VIIIfx */
+#define	TLB_DAR_STLB			(2)	/* SPARC64 V, VI, VII, VIIIfx */
+
+#define	TAR_VPN_SHIFT			(13)
+#define	TAR_CTX_MASK			((1 << TAR_VPN_SHIFT) - 1)
+
+#define	TLB_TAR_VA(va)			((va) & ~TAR_CTX_MASK)
+#define	TLB_TAR_CTX(ctx)		((ctx) & TAR_CTX_MASK)
+
+#define	TLB_CXR_CTX_BITS		(13)
+#define	TLB_CXR_CTX_MASK						\
+	(((1UL << TLB_CXR_CTX_BITS) - 1) << TLB_CXR_CTX_SHIFT)
+#define	TLB_CXR_CTX_SHIFT		(0)
+#define	TLB_CXR_PGSZ_BITS		(3)
+#define	TLB_CXR_PGSZ_MASK		(~TLB_CXR_CTX_MASK)
+#define	TLB_PCXR_N_IPGSZ0_SHIFT		(53)	/* SPARC64 VI, VII, VIIIfx */
+#define	TLB_PCXR_N_IPGSZ1_SHIFT		(50)	/* SPARC64 VI, VII, VIIIfx */
+#define	TLB_PCXR_N_PGSZ0_SHIFT		(61)
+#define	TLB_PCXR_N_PGSZ1_SHIFT		(58)
+#define	TLB_PCXR_N_PGSZ_I_SHIFT		(55)	/* US-IV+ */
+#define	TLB_PCXR_P_IPGSZ0_SHIFT		(24)	/* SPARC64 VI, VII, VIIIfx */
+#define	TLB_PCXR_P_IPGSZ1_SHIFT		(27)	/* SPARC64 VI, VII, VIIIfx */
+#define	TLB_PCXR_P_PGSZ0_SHIFT		(16)
+#define	TLB_PCXR_P_PGSZ1_SHIFT		(19)
+/*
+ * Note that the US-IV+ documentation appears to have TLB_PCXR_P_PGSZ_I_SHIFT
+ * and TLB_PCXR_P_PGSZ0_SHIFT erroneously inverted.
+ */
+#define	TLB_PCXR_P_PGSZ_I_SHIFT		(22)	/* US-IV+ */
+#define	TLB_SCXR_S_PGSZ1_SHIFT		(19)
+#define	TLB_SCXR_S_PGSZ0_SHIFT		(16)
+
+#define	TLB_TAE_PGSZ_BITS		(3)
+#define	TLB_TAE_PGSZ0_MASK						\
+	(((1UL << TLB_TAE_PGSZ_BITS) - 1) << TLB_TAE_PGSZ0_SHIFT)
+#define	TLB_TAE_PGSZ1_MASK						\
+	(((1UL << TLB_TAE_PGSZ_BITS) - 1) << TLB_TAE_PGSZ1_SHIFT)
+#define	TLB_TAE_PGSZ0_SHIFT		(16)
+#define	TLB_TAE_PGSZ1_SHIFT		(19)
+
+#define	TLB_DEMAP_ID_SHIFT		(4)
+#define	TLB_DEMAP_ID_PRIMARY		(0)
+#define	TLB_DEMAP_ID_SECONDARY		(1)
+#define	TLB_DEMAP_ID_NUCLEUS		(2)
+
+#define	TLB_DEMAP_TYPE_SHIFT		(6)
+#define	TLB_DEMAP_TYPE_PAGE		(0)
+#define	TLB_DEMAP_TYPE_CONTEXT		(1)
+#define	TLB_DEMAP_TYPE_ALL		(2)	/* US-III and beyond only */
+
+#define	TLB_DEMAP_VA(va)		((va) & ~PAGE_MASK)
+#define	TLB_DEMAP_ID(id)		((id) << TLB_DEMAP_ID_SHIFT)
+#define	TLB_DEMAP_TYPE(type)		((type) << TLB_DEMAP_TYPE_SHIFT)
+
+#define	TLB_DEMAP_PAGE			(TLB_DEMAP_TYPE(TLB_DEMAP_TYPE_PAGE))
+#define	TLB_DEMAP_CONTEXT		(TLB_DEMAP_TYPE(TLB_DEMAP_TYPE_CONTEXT))
+#define	TLB_DEMAP_ALL			(TLB_DEMAP_TYPE(TLB_DEMAP_TYPE_ALL))
+
+#define	TLB_DEMAP_PRIMARY		(TLB_DEMAP_ID(TLB_DEMAP_ID_PRIMARY))
+#define	TLB_DEMAP_SECONDARY		(TLB_DEMAP_ID(TLB_DEMAP_ID_SECONDARY))
+#define	TLB_DEMAP_NUCLEUS		(TLB_DEMAP_ID(TLB_DEMAP_ID_NUCLEUS))
+
+#define	TLB_CTX_KERNEL			(0)
+#define	TLB_CTX_USER_MIN		(1)
+#define	TLB_CTX_USER_MAX		(8192)
+
+#define	MMU_SFSR_ASI_SHIFT		(16)
+#define	MMU_SFSR_FT_SHIFT		(7)
+#define	MMU_SFSR_E_SHIFT		(6)
+#define	MMU_SFSR_CT_SHIFT		(4)
+#define	MMU_SFSR_PR_SHIFT		(3)
+#define	MMU_SFSR_W_SHIFT		(2)
+#define	MMU_SFSR_OW_SHIFT		(1)
+#define	MMU_SFSR_FV_SHIFT		(0)
+
+#define	MMU_SFSR_ASI_SIZE		(8)
+#define	MMU_SFSR_FT_SIZE		(6)
+#define	MMU_SFSR_CT_SIZE		(2)
+
+#define	MMU_SFSR_GET_ASI(sfsr)						\
+	(((sfsr) >> MMU_SFSR_ASI_SHIFT) & ((1UL << MMU_SFSR_ASI_SIZE) - 1))
+#define	MMU_SFSR_GET_FT(sfsr)						\
+	(((sfsr) >> MMU_SFSR_FT_SHIFT) & ((1UL << MMU_SFSR_FT_SIZE) - 1))
+#define	MMU_SFSR_GET_CT(sfsr)						\
+	(((sfsr) >> MMU_SFSR_CT_SHIFT) & ((1UL << MMU_SFSR_CT_SIZE) - 1))
+
+#define	MMU_SFSR_E			(1UL << MMU_SFSR_E_SHIFT)
+#define	MMU_SFSR_PR			(1UL << MMU_SFSR_PR_SHIFT)
+#define	MMU_SFSR_W			(1UL << MMU_SFSR_W_SHIFT)
+#define	MMU_SFSR_OW			(1UL << MMU_SFSR_OW_SHIFT)
+#define	MMU_SFSR_FV			(1UL << MMU_SFSR_FV_SHIFT)
+
+typedef void tlb_flush_nonlocked_t(void);
+typedef void tlb_flush_user_t(void);
+
+struct pmap;
+struct tlb_entry;
+
+extern int dtlb_slots;
+extern int itlb_slots;
+extern int kernel_tlb_slots;
+extern struct tlb_entry *kernel_tlbs;
+
+void	tlb_context_demap(struct pmap *pm);
+void	tlb_page_demap(struct pmap *pm, vm_offset_t va);
+void	tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end);
+
+tlb_flush_nonlocked_t cheetah_tlb_flush_nonlocked;
+tlb_flush_user_t cheetah_tlb_flush_user;
+
+tlb_flush_nonlocked_t spitfire_tlb_flush_nonlocked;
+tlb_flush_user_t spitfire_tlb_flush_user;
+
+tlb_flush_nonlocked_t zeus_tlb_flush_nonlocked;
+tlb_flush_user_t zeus_tlb_flush_user;
+
+extern tlb_flush_nonlocked_t *tlb_flush_nonlocked;
+extern tlb_flush_user_t *tlb_flush_user;
+
+#endif /* !_MACHINE_TLB_H_ */


Property changes on: trunk/sys/sparc64/include/tlb.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/trap.h
===================================================================
--- trunk/sys/sparc64/include/trap.h	                        (rev 0)
+++ trunk/sys/sparc64/include/trap.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,100 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/trap.h 190107 2009-03-19 20:46:51Z marius $
+ */
+
+#ifndef	_MACHINE_TRAP_H_
+#define	_MACHINE_TRAP_H_
+
+#ifdef _KERNEL
+
+#define	T_RESERVED			0
+#define	T_INSTRUCTION_EXCEPTION		1
+#define	T_INSTRUCTION_ERROR		2
+#define	T_INSTRUCTION_PROTECTION	3
+#define	T_ILLTRAP_INSTRUCTION		4
+#define	T_ILLEGAL_INSTRUCTION		5
+#define	T_PRIVILEGED_OPCODE		6
+#define	T_FP_DISABLED			7
+#define	T_FP_EXCEPTION_IEEE_754		8
+#define	T_FP_EXCEPTION_OTHER		9
+#define	T_TAG_OVERFLOW			10
+#define	T_DIVISION_BY_ZERO		11
+#define	T_DATA_EXCEPTION		12
+#define	T_DATA_ERROR			13
+#define	T_DATA_PROTECTION		14
+#define	T_MEM_ADDRESS_NOT_ALIGNED	15
+#define	T_PRIVILEGED_ACTION		16
+#define	T_ASYNC_DATA_ERROR		17
+#define	T_TRAP_INSTRUCTION_16		18
+#define	T_TRAP_INSTRUCTION_17		19
+#define	T_TRAP_INSTRUCTION_18		20
+#define	T_TRAP_INSTRUCTION_19		21
+#define	T_TRAP_INSTRUCTION_20		22
+#define	T_TRAP_INSTRUCTION_21		23
+#define	T_TRAP_INSTRUCTION_22		24
+#define	T_TRAP_INSTRUCTION_23		25
+#define	T_TRAP_INSTRUCTION_24		26
+#define	T_TRAP_INSTRUCTION_25		27
+#define	T_TRAP_INSTRUCTION_26		28
+#define	T_TRAP_INSTRUCTION_27		29
+#define	T_TRAP_INSTRUCTION_28		30
+#define	T_TRAP_INSTRUCTION_29		31
+#define	T_TRAP_INSTRUCTION_30		32
+#define	T_TRAP_INSTRUCTION_31		33
+#define	T_INSTRUCTION_MISS		34
+#define	T_DATA_MISS			35
+
+#define	T_INTERRUPT			36
+#define	T_PA_WATCHPOINT			37
+#define	T_VA_WATCHPOINT			38
+#define	T_CORRECTED_ECC_ERROR		39
+#define	T_SPILL				40
+#define	T_FILL				41
+#define	T_FILL_RET			42
+#define	T_BREAKPOINT			43
+#define	T_CLEAN_WINDOW			44
+#define	T_RANGE_CHECK			45
+#define	T_FIX_ALIGNMENT			46
+#define	T_INTEGER_OVERFLOW		47
+#define	T_SYSCALL			48
+#define	T_RSTRWP_PHYS			49
+#define	T_RSTRWP_VIRT			50
+#define	T_KSTACK_FAULT			51
+
+#define	T_MAX				(T_KSTACK_FAULT + 1)
+
+#define	T_KERNEL			64
+
+#ifndef LOCORE
+void sun4u_set_traptable(void *tba_addr);
+extern const char *const trap_msg[];
+#endif
+
+#endif
+
+#endif /* !_MACHINE_TRAP_H_ */


Property changes on: trunk/sys/sparc64/include/trap.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/tsb.h
===================================================================
--- trunk/sys/sparc64/include/tsb.h	                        (rev 0)
+++ trunk/sys/sparc64/include/tsb.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,96 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1997 Berkeley Software Design, Inc. 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. Berkeley Software Design Inc's name may not be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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: BSDI: pmap.v9.h,v 1.10.2.6 1999/08/23 22:18:44 cp Exp
+ * $FreeBSD: stable/10/sys/sparc64/include/tsb.h 223378 2011-06-21 20:48:14Z marius $
+ */
+
+#ifndef	_MACHINE_TSB_H_
+#define	_MACHINE_TSB_H_
+
+#define	TSB_PAGES_SHIFT			(4)
+#define	TSB_PAGES			(1 << TSB_PAGES_SHIFT)
+#define	TSB_BSHIFT			(TSB_PAGES_SHIFT + PAGE_SHIFT)
+#define	TSB_BSIZE			(1 << TSB_BSHIFT)
+#define	TSB_BUCKET_SHIFT		(2)
+#define	TSB_BUCKET_SIZE			(1 << TSB_BUCKET_SHIFT)
+#define	TSB_BUCKET_ADDRESS_BITS \
+	(TSB_BSHIFT - TSB_BUCKET_SHIFT - TTE_SHIFT)
+#define	TSB_BUCKET_MASK			((1 << TSB_BUCKET_ADDRESS_BITS) - 1)
+
+#ifndef LOCORE
+
+#define	TSB_SIZE			(TSB_BSIZE / sizeof(struct tte))
+
+extern struct tte *tsb_kernel;
+extern vm_size_t tsb_kernel_mask;
+extern vm_size_t tsb_kernel_size;
+extern vm_paddr_t tsb_kernel_phys;
+
+static __inline struct tte *
+tsb_vpntobucket(pmap_t pm, vm_offset_t vpn)
+{
+
+	return (&pm->pm_tsb[(vpn & TSB_BUCKET_MASK) << TSB_BUCKET_SHIFT]);
+}
+
+static __inline struct tte *
+tsb_vtobucket(pmap_t pm, u_long sz, vm_offset_t va)
+{
+
+	return (tsb_vpntobucket(pm, va >> TTE_PAGE_SHIFT(sz)));
+}
+
+static __inline struct tte *
+tsb_kvpntotte(vm_offset_t vpn)
+{
+
+	return (&tsb_kernel[vpn & tsb_kernel_mask]);
+}
+
+static __inline struct tte *
+tsb_kvtotte(vm_offset_t va)
+{
+
+	return (tsb_kvpntotte(va >> PAGE_SHIFT));
+}
+
+typedef int (tsb_callback_t)(struct pmap *, struct pmap *, struct tte *,
+	    vm_offset_t);
+
+struct	tte *tsb_tte_lookup(pmap_t pm, vm_offset_t va);
+void	tsb_tte_remove(struct tte *stp);
+struct	tte *tsb_tte_enter(pmap_t pm, vm_page_t m, vm_offset_t va, u_long sz,
+	    u_long data);
+void	tsb_tte_local_remove(struct tte *tp);
+void	tsb_foreach(pmap_t pm1, pmap_t pm2, vm_offset_t start, vm_offset_t end,
+	    tsb_callback_t *callback);
+
+#endif /* !LOCORE */
+
+#endif /* !_MACHINE_TSB_H_ */


Property changes on: trunk/sys/sparc64/include/tsb.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/tstate.h
===================================================================
--- trunk/sys/sparc64/include/tstate.h	                        (rev 0)
+++ trunk/sys/sparc64/include/tstate.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,83 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2001 by Thomas Moestl <tmm at 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, 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 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/tstate.h 88631 2001-12-29 07:11:00Z jake $
+ */
+
+#ifndef	_MACHINE_TSTATE_H_
+#define	_MACHINE_TSTATE_H_
+
+#include <machine/pstate.h>
+#include <machine/ccr.h>
+
+#define	TSTATE_CWP_SHIFT	0
+#define	TSTATE_CWP_BITS		5
+#define	TSTATE_CWP_MASK \
+	(((1 << TSTATE_CWP_BITS) - 1) << TSTATE_CWP_SHIFT)
+#define	TSTATE_CWP(x)		((x & TSTATE_CWP_MASK) >> TSTATE_CWP_SHIFT)
+
+#define	TSTATE_PSTATE_SHIFT	8
+#define	TSTATE_PSTATE_BITS	12
+#define	TSTATE_PSTATE_MASK \
+	(((1 << TSTATE_PSTATE_BITS) - 1) << TSTATE_PSTATE_SHIFT)
+#define	TSTATE_PSTATE(x)	((x) << TSTATE_PSTATE_SHIFT)
+#define	TSTATE_AG		TSTATE_PSTATE(PSTATE_AG)
+#define	TSTATE_IE		TSTATE_PSTATE(PSTATE_IE)
+#define	TSTATE_PRIV		TSTATE_PSTATE(PSTATE_PRIV)
+#define	TSTATE_AM		TSTATE_PSTATE(PSTATE_AM)
+#define	TSTATE_PEF		TSTATE_PSTATE(PSTATE_PEF)
+#define	TSTATE_RED		TSTATE_PSTATE(PSTATE_RED)
+#define	TSTATE_MM_TSO		TSTATE_PSTATE(PSTATE_MM_TSO)
+#define	TSTATE_MM_PSO		TSTATE_PSTATE(PSTATE_MM_PSO)
+#define	TSTATE_MM_RMO		TSTATE_PSTATE(PSTATE_MM_RMO)
+#define	TSTATE_TLE		TSTATE_PSTATE(PSTATE_TLE)
+#define	TSTATE_CLE		TSTATE_PSTATE(PSTATE_CLE)
+#define	TSTATE_MG		TSTATE_PSTATE(PSTATE_MG)
+#define	TSTATE_IG		TSTATE_PSTATE(PSTATE_IG)
+
+#define	TSTATE_ASI_SHIFT	24
+#define	TSTATE_ASI_BITS		8
+#define	TSTATE_ASI_MASK	\
+	(((1 << TSTATE_ASI_BITS) - 1) << TSTATE_ASI_SHIFT)
+#define	TSTATE_ASI(x)		((x & TSTATE_ASI_MASK) >> TSTATE_ASI_SHIFT)
+
+#define	TSTATE_CCR_SHIFT	32
+#define	TSTATE_ICC_SHIFT	(TSTATE_CCR_SHIFT + ICC_SHIFT)
+#define	TSTATE_ICC_MASK		(ICC_MASK << TSTATE_CCR_SHIFT)
+#define	TSTATE_XCC_SHIFT	(TSTATE_CCR_SHIFT + XCC_SHIFT)
+#define	TSTATE_XCC_MASK		(XCC_MASK << TSTATE_CCR_SHIFT)
+#define	TSTATE_CCR(x)		((x) << TSTATE_CCR_SHIFT)
+#define	TSTATE_ICC_C		TSTATE_CCR(ICC_C)
+#define	TSTATE_ICC_V		TSTATE_CCR(ICC_V)
+#define	TSTATE_ICC_Z		TSTATE_CCR(ICC_Z)
+#define	TSTATE_ICC_N		TSTATE_CCR(ICC_N)
+#define	TSTATE_XCC_C		TSTATE_CCR(XCC_C)
+#define	TSTATE_XCC_V		TSTATE_CCR(XCC_V)
+#define	TSTATE_XCC_Z		TSTATE_CCR(XCC_Z)
+#define	TSTATE_XCC_N		TSTATE_CCR(XCC_N)
+
+#define	TSTATE_SECURE(tstate) \
+	PSTATE_SECURE(((tstate) >> TSTATE_PSTATE_SHIFT) & ((1 << TSTATE_PSTATE_BITS) - 1))
+
+#endif /* !_MACHINE_TSTATE_H_ */


Property changes on: trunk/sys/sparc64/include/tstate.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/tte.h
===================================================================
--- trunk/sys/sparc64/include/tte.h	                        (rev 0)
+++ trunk/sys/sparc64/include/tte.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,167 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1997 Berkeley Software Design, Inc. 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. Berkeley Software Design Inc's name may not be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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: BSDI: pmap.v9.h,v 1.10.2.6 1999/08/23 22:18:44 cp Exp
+ * $FreeBSD: stable/10/sys/sparc64/include/tte.h 205258 2010-03-17 20:23:14Z marius $
+ */
+
+#ifndef	_MACHINE_TTE_H_
+#define	_MACHINE_TTE_H_
+
+#define	TTE_SHIFT	(5)
+
+#define	TD_SIZE_SHIFT	(61)
+#define	TD_SOFT2_SHIFT	(50)
+#define	TD_RSVD2_SHIFT	(49)
+#define	TD_SIZE2_SHIFT	(48)
+#define	TD_DIAG_SF_SHIFT	(41)
+#define	TD_RSVD_CH_SHIFT	(43)
+#define	TD_RSVD_OC_SHIFT	(47)
+#define	TD_RSVD_PT_SHIFT	TD_RSVD_CH_SHIFT
+#define	TD_RSVD_VE_SHIFT	(41)
+#define	TD_PA_SHIFT	(13)
+#define	TD_SOFT_SHIFT	(7)
+
+#define	TD_SIZE_BITS	(2)
+#define	TD_SOFT2_BITS	(9)
+#define	TD_RSVD2_BITS	(1)	/* US-IV+, SPARC64 VI, VII, VIIIfx */
+#define	TD_SIZE2_BITS	(1)	/* US-IV+, SPARC64 VI, VII, VIIIfx */
+#define	TD_DIAG_SF_BITS	(9)	/* US-I, II{,e,i} */
+#define	TD_RSVD_CH_BITS	(7)	/* US-III{,i,+}, US-IV, SPARC64 V */
+#define	TD_RSVD_OC_BITS	(1)	/* SPARC64 VI, VII */
+#define	TD_RSVD_PT_BITS	(5)	/* US-IV+, SPARC64 VI, VII */
+#define	TD_RSVD_VE_BITS	(7)	/* SPARC64 VIIIfx */
+#define	TD_PA_CH_BITS	(30)	/* US-III{,i,+}, US-IV{,+}, SPARC64 V */
+#define	TD_PA_OC_BITS	(34)	/* SPARC64 VI, VII */
+#define	TD_PA_SF_BITS	(28)	/* US-I, II{,e,i}, SPARC64 VIIIfx */
+#define	TD_PA_BITS	TD_PA_CH_BITS
+#define	TD_SOFT_BITS	(6)
+
+#define	TD_SIZE_MASK	((1UL << TD_SIZE_BITS) - 1)
+#define	TD_SOFT2_MASK	((1UL << TD_SOFT2_BITS) - 1)
+#define	TD_RSVD2_MASK	((1UL << TD_RSVD2_BITS) - 1)
+#define	TD_SIZE2_MASK	((1UL << TD_SIZE2_BITS) - 1)
+#define	TD_DIAG_SF_MASK	((1UL << TD_DIAG_SF_BITS) - 1)
+#define	TD_RSVD_CH_MASK	((1UL << TD_RSVD_CH_BITS) - 1)
+#define	TD_RSVD_OC_MASK	((1UL << TD_RSVD_OC_BITS) - 1)
+#define	TD_RSVD_PT_MASK	((1UL << TD_RSVD_PT_BITS) - 1)
+#define	TD_RSVD_VE_MASK	((1UL << TD_RSVD_VE_BITS) - 1)
+#define	TD_PA_CH_MASK	((1UL << TD_PA_CH_BITS) - 1)
+#define	TD_PA_OC_MASK	((1UL << TD_PA_OC_BITS) - 1)
+#define	TD_PA_SF_MASK	((1UL << TD_PA_SF_BITS) - 1)
+#define	TD_PA_MASK	((1UL << TD_PA_BITS) - 1)
+#define	TD_SOFT_MASK	((1UL << TD_SOFT_BITS) - 1)
+
+#define	TS_8K		(0UL)
+#define	TS_64K		(1UL)
+#define	TS_512K		(2UL)
+#define	TS_4M		(3UL)
+#define	TS_32M		(4UL)	/* US-IV+, SPARC64 VI, VII only */
+#define	TS_256M		(5UL)	/* US-IV+, SPARC64 VI, VII only */
+#define	TS_2G		(6UL)	/* SPARC64 VIIIfx only */
+
+#define	TS_MIN		TS_8K
+#define	TS_MAX		TS_4M
+
+#define	TD_V		(1UL << 63)
+#define	TD_8K		(TS_8K << TD_SIZE_SHIFT)
+#define	TD_64K		(TS_64K << TD_SIZE_SHIFT)
+#define	TD_512K		(TS_512K << TD_SIZE_SHIFT)
+#define	TD_4M		(TS_4M << TD_SIZE_SHIFT)
+#define	TD_32M								\
+	(((TS_32M & TD_SIZE_MASK) << TD_SIZE_SHIFT) |			\
+	(TD_SIZE2_MASK << TD_SIZE2_SHIFT))
+#define	TD_256M								\
+	(((TS_256M & TD_SIZE_MASK) << TD_SIZE_SHIFT) |			\
+	(TD_SIZE2_MASK << TD_SIZE2_SHIFT))
+#define	TD_2G								\
+	(((TS_2G & TD_SIZE_MASK) << TD_SIZE_SHIFT) |			\
+	(TD_SIZE2_MASK << TD_SIZE2_SHIFT))
+#define	TD_NFO		(1UL << 60)
+#define	TD_IE		(1UL << 59)
+#define	TD_PA(pa)	((pa) & (TD_PA_MASK << TD_PA_SHIFT))
+/* NOTE: bit 6 of TD_SOFT will be sign-extended if used as an immediate. */
+#define	TD_FAKE		((1UL << 5) << TD_SOFT_SHIFT)
+#define	TD_EXEC		((1UL << 4) << TD_SOFT_SHIFT)
+#define	TD_REF		((1UL << 3) << TD_SOFT_SHIFT)
+#define	TD_PV		((1UL << 2) << TD_SOFT_SHIFT)
+#define	TD_SW		((1UL << 1) << TD_SOFT_SHIFT)
+#define	TD_WIRED	((1UL << 0) << TD_SOFT_SHIFT)
+#define	TD_L		(1UL << 6)
+#define	TD_CP		(1UL << 5)
+#define	TD_CV		(1UL << 4)
+#define	TD_E		(1UL << 3)
+#define	TD_P		(1UL << 2)
+#define	TD_W		(1UL << 1)
+#define	TD_G		(1UL << 0)
+
+#define	TV_SIZE_BITS	(TD_SIZE_BITS)
+#define	TV_VPN(va, sz)	((((va) >> TTE_PAGE_SHIFT(sz)) << TV_SIZE_BITS) | sz)
+
+#define	TTE_SIZE_SPREAD	(3)
+#define	TTE_PAGE_SHIFT(sz)						\
+	(PAGE_SHIFT + ((sz) * TTE_SIZE_SPREAD))
+
+#define	TTE_GET_SIZE(tp)						\
+	(((tp)->tte_data >> TD_SIZE_SHIFT) & TD_SIZE_MASK)
+#define	TTE_GET_PAGE_SHIFT(tp)						\
+	TTE_PAGE_SHIFT(TTE_GET_SIZE(tp))
+#define	TTE_GET_PAGE_SIZE(tp)						\
+	(1 << TTE_GET_PAGE_SHIFT(tp))
+#define	TTE_GET_PAGE_MASK(tp)						\
+	(TTE_GET_PAGE_SIZE(tp) - 1)
+
+#define	TTE_GET_PA(tp)							\
+	((tp)->tte_data & (TD_PA_MASK << TD_PA_SHIFT))
+#define	TTE_GET_VPN(tp)							\
+	((tp)->tte_vpn >> TV_SIZE_BITS)
+#define	TTE_GET_VA(tp)							\
+	(TTE_GET_VPN(tp) << TTE_GET_PAGE_SHIFT(tp))
+#define	TTE_GET_PMAP(tp)						\
+	(((tp)->tte_data & TD_P) != 0 ?	(kernel_pmap) :			\
+	(PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)(tp)))->md.pmap))
+#define	TTE_ZERO(tp)							\
+	memset(tp, 0, sizeof(*tp))
+
+struct pmap;
+
+struct tte {
+	u_long	tte_vpn;
+	u_long	tte_data;
+	TAILQ_ENTRY(tte) tte_link;
+};
+
+static __inline int
+tte_match(struct tte *tp, vm_offset_t va)
+{
+
+	return (((tp->tte_data & TD_V) != 0) &&
+	    (tp->tte_vpn == TV_VPN(va, TTE_GET_SIZE(tp))));
+}
+
+#endif /* !_MACHINE_TTE_H_ */


Property changes on: trunk/sys/sparc64/include/tte.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/ucontext.h
===================================================================
--- trunk/sys/sparc64/include/ucontext.h	                        (rev 0)
+++ trunk/sys/sparc64/include/ucontext.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,65 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999 Marcel Moolenaar
+ * 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
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *	from: FreeBSD: src/sys/alpha/include/ucontext.h,v 1.3 1999/10/08
+ * $FreeBSD: stable/10/sys/sparc64/include/ucontext.h 253266 2013-07-12 14:24:52Z marius $
+ */
+
+#ifndef _MACHINE_UCONTEXT_H_
+#define	_MACHINE_UCONTEXT_H_
+
+struct __mcontext {
+	uint64_t mc_global[8];
+	uint64_t mc_out[8];
+	uint64_t mc_local[8];
+	uint64_t mc_in[8];
+	uint32_t mc_fp[64];
+} __aligned(64);
+
+typedef struct __mcontext mcontext_t;
+
+#define	_mc_flags	mc_global[0]
+#define	_mc_sp		mc_out[6]
+#define	_mc_fprs	mc_local[0]
+#define	_mc_fsr		mc_local[1]
+#define	_mc_gsr		mc_local[2]
+#define	_mc_tnpc	mc_in[0]
+#define	_mc_tpc		mc_in[1]
+#define	_mc_tstate	mc_in[2]
+#define	_mc_y		mc_in[4]
+#define	_mc_wstate	mc_in[5]
+
+#define	_MC_VERSION_SHIFT	0
+#define	_MC_VERSION_BITS	32
+#define	_MC_VERSION		1L
+
+#define	_MC_FLAGS_SHIFT		32
+#define	_MC_FLAGS_BITS		32
+#define	_MC_VOLUNTARY		((1L << 0) << _MC_FLAGS_SHIFT)
+
+#endif /* !_MACHINE_UCONTEXT_H_ */


Property changes on: trunk/sys/sparc64/include/ucontext.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/upa.h
===================================================================
--- trunk/sys/sparc64/include/upa.h	                        (rev 0)
+++ trunk/sys/sparc64/include/upa.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,42 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 by Thomas Moestl <tmm at 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, 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 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/upa.h 203838 2010-02-13 16:52:33Z marius $
+ */
+
+#ifndef _MACHINE_UPA_H_
+#define	_MACHINE_UPA_H_
+
+#define	UPA_MEMSTART	0x1c000000000UL
+#define	UPA_MEMEND	0x1ffffffffffUL
+
+#define	UPA_CR_MID_SHIFT	(17)
+#define	UPA_CR_MID_SIZE		(5)
+#define	UPA_CR_MID_MASK							\
+	(((1 << UPA_CR_MID_SIZE) - 1) << UPA_CR_MID_SHIFT)
+
+#define	UPA_CR_GET_MID(cr)	((cr & UPA_CR_MID_MASK) >> UPA_CR_MID_SHIFT)
+
+#endif /* _MACHINE_UPA_H_ */


Property changes on: trunk/sys/sparc64/include/upa.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/utrap.h
===================================================================
--- trunk/sys/sparc64/include/utrap.h	                        (rev 0)
+++ trunk/sys/sparc64/include/utrap.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,111 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/utrap.h 154419 2006-01-16 01:35:25Z kris $
+ */
+
+#ifndef	_MACHINE_UTRAP_H_
+#define	_MACHINE_UTRAP_H_
+
+#define	UT_INSTRUCTION_EXCEPTION	1
+#define	UT_INSTRUCTION_ERROR		2
+#define	UT_INSTRUCTION_PROTECTION	3
+#define	UT_ILLTRAP_INSTRUCTION		4
+#define	UT_ILLEGAL_INSTRUCTION		5
+#define	UT_PRIVILEGED_OPCODE		6
+#define	UT_FP_DISABLED			7
+#define	UT_FP_EXCEPTION_IEEE_754	8
+#define	UT_FP_EXCEPTION_OTHER		9
+#define	UT_TAG_OVERFLOW			10
+#define	UT_DIVISION_BY_ZERO		11
+#define	UT_DATA_EXCEPTION		12
+#define	UT_DATA_ERROR			13
+#define	UT_DATA_PROTECTION		14
+#define	UT_MEM_ADDRESS_NOT_ALIGNED	15
+#define	UT_PRIVILEGED_ACTION		16
+#define	UT_ASYNC_DATA_ERROR		17
+#define	UT_TRAP_INSTRUCTION_16		18
+#define	UT_TRAP_INSTRUCTION_17		19
+#define	UT_TRAP_INSTRUCTION_18		20
+#define	UT_TRAP_INSTRUCTION_19		21
+#define	UT_TRAP_INSTRUCTION_20		22
+#define	UT_TRAP_INSTRUCTION_21		23
+#define	UT_TRAP_INSTRUCTION_22		24
+#define	UT_TRAP_INSTRUCTION_23		25
+#define	UT_TRAP_INSTRUCTION_24		26
+#define	UT_TRAP_INSTRUCTION_25		27
+#define	UT_TRAP_INSTRUCTION_26		28
+#define	UT_TRAP_INSTRUCTION_27		29
+#define	UT_TRAP_INSTRUCTION_28		30
+#define	UT_TRAP_INSTRUCTION_29		31
+#define	UT_TRAP_INSTRUCTION_30		32
+#define	UT_TRAP_INSTRUCTION_31		33
+#define	UT_INSTRUCTION_MISS		34
+#define	UT_DATA_MISS			35
+#define	UT_MAX				36
+
+#define	ST_SUNOS_SYSCALL		0
+#define	ST_BREAKPOINT			1
+#define	ST_DIVISION_BY_ZERO		2
+#define	ST_FLUSH_WINDOWS		3	/* XXX implement! */
+#define	ST_CLEAN_WINDOW			4
+#define	ST_RANGE_CHECK			5
+#define	ST_FIX_ALIGNMENT		6
+#define	ST_INTEGER_OVERFLOW		7
+/* 8 is 32-bit ABI syscall (old solaris syscall?) */
+#define	ST_BSD_SYSCALL			9
+#define	ST_FP_RESTORE			10
+/* 11-15 are available */
+/* 16 is linux 32 bit syscall (but supposed to be reserved, grr) */
+/* 17 is old linux 64 bit syscall (but supposed to be reserved, grr) */
+/* 16-31 are reserved for user applications (utraps) */
+#define	ST_GETCC			32	/* XXX implement! */
+#define	ST_SETCC			33	/* XXX implement! */
+#define	ST_GETPSR			34	/* XXX implement! */
+#define	ST_SETPSR			35	/* XXX implement! */
+/* 36-63 are available */
+#define	ST_SOLARIS_SYSCALL		64
+#define	ST_SYSCALL			65
+#define	ST_SYSCALL32			66
+/* 67 is reserved to OS source licensee */
+/* 68 is return from deferred trap (not supported) */
+/* 69-95 are reserved to SPARC international */
+/* 96-108 are available */
+/* 109 is linux 64 bit syscall */
+/* 110 is linux 64 bit getcontext (?) */
+/* 111 is linux 64 bit setcontext (?) */
+/* 112-255 are available */
+
+#define	UTH_NOCHANGE			(-1)
+
+#ifndef __ASM__
+
+typedef	int utrap_entry_t;
+typedef void *utrap_handler_t;
+
+#endif
+
+#endif


Property changes on: trunk/sys/sparc64/include/utrap.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/varargs.h
===================================================================
--- trunk/sys/sparc64/include/varargs.h	                        (rev 0)
+++ trunk/sys/sparc64/include/varargs.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,88 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 David E. O'Brien.  All rights reserved.
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 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.
+ *
+ *	@(#)varargs.h	8.3 (Berkeley) 3/22/94
+ * $FreeBSD: stable/10/sys/sparc64/include/varargs.h 219608 2011-03-13 13:42:43Z marius $
+ */
+
+#ifndef _MACHINE_VARARGS_H_
+#define	_MACHINE_VARARGS_H_
+
+#ifndef _SYS_CDEFS_H_
+#error this file needs sys/cdefs.h as a prerequisite
+#endif
+
+#ifdef __GNUCLIKE_BUILTIN_VARARGS
+
+#include <sys/_types.h>
+
+#ifndef _VA_LIST_DECLARED
+#define	_VA_LIST_DECLARED
+typedef	__va_list	va_list;
+#endif
+
+typedef int __builtin_va_alist_t __attribute__((__mode__(__word__)));
+
+#define	va_alist		__builtin_va_alist
+#define	va_dcl			__builtin_va_alist_t __builtin_va_alist; ...
+#define	va_start(ap)		__builtin_varargs_start(ap)
+#define	va_arg(ap, type)	__builtin_va_arg((ap), type)
+#define	va_end(ap)		__builtin_va_end(ap)
+
+#else	/* !__GNUCLIKE_BUILTIN_VARARGS */
+
+#include <machine/stdarg.h>
+
+#define	__va_ellipsis	...
+
+#define	va_alist	__builtin_va_alist
+#define	va_dcl		long __builtin_va_alist; __va_ellipsis
+
+#undef va_start
+#define	va_start(ap) \
+	((ap) = (va_list)__builtin_saveregs())
+
+#endif /* __GNUCLIKE_BUILTIN_VARARGS */
+
+#endif /* !_MACHINE_VARARGS_H_ */


Property changes on: trunk/sys/sparc64/include/varargs.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/vdso.h
===================================================================
--- trunk/sys/sparc64/include/vdso.h	                        (rev 0)
+++ trunk/sys/sparc64/include/vdso.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,35 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2012 Konstantin Belousov <kib at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/vdso.h 237433 2012-06-22 07:06:40Z kib $
+ */
+
+#ifndef _SPARC64_VDSO_H
+#define	_SPARC64_VDSO_H
+
+#define	VDSO_TIMEHANDS_MD			\
+	uint32_t	th_res[8];
+
+#endif


Property changes on: trunk/sys/sparc64/include/vdso.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/ver.h
===================================================================
--- trunk/sys/sparc64/include/ver.h	                        (rev 0)
+++ trunk/sys/sparc64/include/ver.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,93 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/ver.h 205263 2010-03-17 21:00:39Z marius $
+ */
+
+#ifndef	_MACHINE_VER_H_
+#define	_MACHINE_VER_H_
+
+#define	VER_MANUF_SHIFT		(48)
+#define	VER_IMPL_SHIFT		(32)
+#define	VER_MASK_SHIFT		(24)
+#define	VER_MAXTL_SHIFT		(8)
+#define	VER_MAXWIN_SHIFT	(0)
+
+#define	VER_MANUF_SIZE		(16)
+#define	VER_IMPL_SIZE		(16)
+#define	VER_MASK_SIZE		(8)
+#define	VER_MAXTL_SIZE		(8)
+#define	VER_MAXWIN_SIZE		(5)
+
+#ifndef LOCORE
+
+#define	VER_MANUF_MASK							\
+	(((1UL << VER_MANUF_SIZE) - 1) << VER_MANUF_SHIFT)
+#define	VER_IMPL_MASK							\
+	(((1UL << VER_IMPL_SIZE) - 1) << VER_IMPL_SHIFT)
+#define	VER_MASK_MASK							\
+	(((1UL << VER_MASK_SIZE) - 1) << VER_MASK_SHIFT)
+#define	VER_MAXTL_MASK							\
+	(((1UL << VER_MAXTL_SIZE) - 1) << VER_MAXTL_SHIFT)
+#define	VER_MAXWIN_MASK							\
+	(((1UL << VER_MAXWIN_SIZE) - 1) << VER_MAXWIN_SHIFT)
+
+#define	VER_MANUF(ver)							\
+	(((ver) & VER_MANUF_MASK) >> VER_MANUF_SHIFT)
+#define	VER_IMPL(ver)							\
+	(((ver) & VER_IMPL_MASK) >> VER_IMPL_SHIFT)
+#define	VER_MASK(ver)							\
+	(((ver) & VER_MASK_MASK) >> VER_MASK_SHIFT)
+#define	VER_MAXTL(ver)							\
+	(((ver) & VER_MAXTL_MASK) >> VER_MAXTL_SHIFT)
+#define	VER_MAXWIN(ver)							\
+	(((ver) & VER_MAXWIN_MASK) >> VER_MAXWIN_SHIFT)
+
+extern char sparc64_model[];
+
+#endif /* !LOCORE */
+
+/* Known implementations */
+#define	CPU_IMPL_SPARC64		0x01
+#define	CPU_IMPL_SPARC64II		0x02
+#define	CPU_IMPL_SPARC64III		0x03
+#define	CPU_IMPL_SPARC64IV		0x04
+#define	CPU_IMPL_SPARC64V		0x05
+#define	CPU_IMPL_SPARC64VI		0x06
+#define	CPU_IMPL_SPARC64VII		0x07
+#define	CPU_IMPL_SPARC64VIIIfx		0x08
+#define	CPU_IMPL_ULTRASPARCI		0x10
+#define	CPU_IMPL_ULTRASPARCII		0x11
+#define	CPU_IMPL_ULTRASPARCIIi		0x12
+#define	CPU_IMPL_ULTRASPARCIIe		0x13
+#define	CPU_IMPL_ULTRASPARCIII		0x14
+#define	CPU_IMPL_ULTRASPARCIIIp		0x15
+#define	CPU_IMPL_ULTRASPARCIIIi		0x16
+#define	CPU_IMPL_ULTRASPARCIV		0x18
+#define	CPU_IMPL_ULTRASPARCIVp		0x19
+#define	CPU_IMPL_ULTRASPARCIIIip	0x22
+
+#endif /* !_MACHINE_VER_H_ */


Property changes on: trunk/sys/sparc64/include/ver.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/vm.h
===================================================================
--- trunk/sys/sparc64/include/vm.h	                        (rev 0)
+++ trunk/sys/sparc64/include/vm.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,36 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Alan L. Cox <alc at cs.rice.edu>
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/vm.h 195649 2009-07-12 23:31:20Z alc $
+ */
+
+#ifndef _MACHINE_VM_H_
+#define	_MACHINE_VM_H_
+
+/* Memory attribute configuration is not (yet) implemented. */
+#define	VM_MEMATTR_DEFAULT	0
+
+#endif /* !_MACHINE_VM_H_ */


Property changes on: trunk/sys/sparc64/include/vm.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/vmparam.h
===================================================================
--- trunk/sys/sparc64/include/vmparam.h	                        (rev 0)
+++ trunk/sys/sparc64/include/vmparam.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,243 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ * Copyright (c) 1994 John S. Dyson
+ * 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.
+ * 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: @(#)vmparam.h     5.9 (Berkeley) 5/12/91
+ *	from: FreeBSD: src/sys/i386/include/vmparam.h,v 1.33 2000/03/30
+ * $FreeBSD: stable/10/sys/sparc64/include/vmparam.h 266204 2014-05-16 01:30:30Z ian $
+ */
+
+#ifndef	_MACHINE_VMPARAM_H_
+#define	_MACHINE_VMPARAM_H_
+
+/*
+ * Virtual memory related constants, all in bytes
+ */
+#ifndef MAXTSIZ
+#define	MAXTSIZ		(1*1024*1024*1024)	/* max text size */
+#endif
+#ifndef DFLDSIZ
+#define	DFLDSIZ		(128*1024*1024)		/* initial data size limit */
+#endif
+#ifndef MAXDSIZ
+#define	MAXDSIZ		(1*1024*1024*1024)	/* max data size */
+#endif
+#ifndef	DFLSSIZ
+#define	DFLSSIZ		(128*1024*1024)		/* initial stack size limit */
+#endif
+#ifndef	MAXSSIZ
+#define	MAXSSIZ		(1*1024*1024*1024)	/* max stack size */
+#endif
+#ifndef	SGROWSIZ
+#define	SGROWSIZ	(128*1024)		/* amount to grow stack */
+#endif
+
+/*
+ * The physical address space is sparsely populated.
+ */
+#define	VM_PHYSSEG_SPARSE
+
+/*
+ * The number of PHYSSEG entries must be one greater than the number
+ * of phys_avail entries because the phys_avail entry that spans the
+ * largest physical address that is accessible by ISA DMA is split
+ * into two PHYSSEG entries.
+ */
+#define	VM_PHYSSEG_MAX		64
+
+/*
+ * Create three free page pools: VM_FREEPOOL_DEFAULT is the default pool
+ * from which physical pages are allocated and VM_FREEPOOL_DIRECT is
+ * the pool from which physical pages for small UMA objects are
+ * allocated.
+ */
+#define	VM_NFREEPOOL		3
+#define	VM_FREEPOOL_CACHE	2
+#define	VM_FREEPOOL_DEFAULT	0
+#define	VM_FREEPOOL_DIRECT	1
+
+/*
+ * Create two free page lists: VM_FREELIST_DEFAULT is for physical
+ * pages that are above the largest physical address that is
+ * accessible by ISA DMA and VM_FREELIST_ISADMA is for physical pages
+ * that are below that address.
+ */
+#define	VM_NFREELIST		2
+#define	VM_FREELIST_DEFAULT	0
+#define	VM_FREELIST_ISADMA	1
+
+/*
+ * An allocation size of 16MB is supported in order to optimize the
+ * use of the direct map by UMA.  Specifically, a cache line contains
+ * at most four TTEs, collectively mapping 16MB of physical memory.
+ * By reducing the number of distinct 16MB "pages" that are used by UMA,
+ * the physical memory allocator reduces the likelihood of both 4MB
+ * page TLB misses and cache misses caused by 4MB page TLB misses.
+ */
+#define	VM_NFREEORDER		12
+
+/*
+ * Enable superpage reservations: 1 level.
+ */
+#ifndef	VM_NRESERVLEVEL
+#define	VM_NRESERVLEVEL		1
+#endif
+
+/*
+ * Level 0 reservations consist of 512 pages.
+ */
+#ifndef	VM_LEVEL_0_ORDER
+#define	VM_LEVEL_0_ORDER	9
+#endif
+
+/**
+ * Address space layout.
+ *
+ * UltraSPARC I and II implement a 44 bit virtual address space.  The address
+ * space is split into 2 regions at each end of the 64 bit address space, with
+ * an out of range "hole" in the middle.  UltraSPARC III implements the full
+ * 64 bit virtual address space, but we don't really have any use for it and
+ * 43 bits of user address space is considered to be "enough", so we ignore it.
+ *
+ * Upper region:	0xffffffffffffffff
+ *			0xfffff80000000000
+ *
+ * Hole:		0xfffff7ffffffffff
+ *			0x0000080000000000
+ *
+ * Lower region:	0x000007ffffffffff
+ *			0x0000000000000000
+ *
+ * In general we ignore the upper region, and use the lower region as mappable
+ * space.
+ *
+ * We define some interesting address constants:
+ *
+ * VM_MIN_ADDRESS and VM_MAX_ADDRESS define the start and end of the entire
+ * 64 bit address space, mostly just for convenience.
+ *
+ * VM_MIN_DIRECT_ADDRESS and VM_MAX_DIRECT_ADDRESS define the start and end
+ * of the direct mapped region.  This maps virtual addresses to physical
+ * addresses directly using 4mb tlb entries, with the physical address encoded
+ * in the lower 43 bits of virtual address.  These mappings are convenient
+ * because they do not require page tables, and because they never change they
+ * do not require tlb flushes.  However, since these mappings are cacheable,
+ * we must ensure that all pages accessed this way are either not double
+ * mapped, or that all other mappings have virtual color equal to physical
+ * color, in order to avoid creating illegal aliases in the data cache.
+ *
+ * VM_MIN_KERNEL_ADDRESS and VM_MAX_KERNEL_ADDRESS define the start and end of
+ * mappable kernel virtual address space.  VM_MIN_KERNEL_ADDRESS is basically
+ * arbitrary, a convenient address is chosen which allows both the kernel text
+ * and data and the prom's address space to be mapped with 1 4mb tsb page.
+ * VM_MAX_KERNEL_ADDRESS is variable, computed at startup time based on the
+ * amount of physical memory available.  Each 4mb tsb page provides 1g of
+ * virtual address space, with the only practical limit being available
+ * phsyical memory.
+ *
+ * VM_MIN_PROM_ADDRESS and VM_MAX_PROM_ADDRESS define the start and end of the
+ * prom address space.  On startup the prom's mappings are duplicated in the
+ * kernel tsb, to allow prom memory to be accessed normally by the kernel.
+ *
+ * VM_MIN_USER_ADDRESS and VM_MAX_USER_ADDRESS define the start and end of the
+ * user address space.  There are some hardware errata about using addresses
+ * at the boundary of the va hole, so we allow just under 43 bits of user
+ * address space.  Note that the kernel and user address spaces overlap, but
+ * this doesn't matter because they use different tlb contexts, and because
+ * the kernel address space is not mapped into each process' address space.
+ */
+#define	VM_MIN_ADDRESS		(0x0000000000000000UL)
+#define	VM_MAX_ADDRESS		(0xffffffffffffffffUL)
+
+#define	VM_MIN_DIRECT_ADDRESS	(0xfffff80000000000UL)
+#define	VM_MAX_DIRECT_ADDRESS	(VM_MAX_ADDRESS)
+
+#define	VM_MIN_KERNEL_ADDRESS	(0x00000000c0000000UL)
+#define	VM_MAX_KERNEL_ADDRESS	(vm_max_kernel_address)
+
+#define	VM_MIN_PROM_ADDRESS	(0x00000000f0000000UL)
+#define	VM_MAX_PROM_ADDRESS	(0x00000000ffffffffUL)
+
+#define	VM_MIN_USER_ADDRESS	(0x0000000000000000UL)
+#define	VM_MAX_USER_ADDRESS	(0x000007fe00000000UL)
+
+#define	VM_MINUSER_ADDRESS	(VM_MIN_USER_ADDRESS)
+#define	VM_MAXUSER_ADDRESS	(VM_MAX_USER_ADDRESS)
+
+#define	KERNBASE		(VM_MIN_KERNEL_ADDRESS)
+#define	PROMBASE		(VM_MIN_PROM_ADDRESS)
+#define	USRSTACK		(VM_MAX_USER_ADDRESS)
+
+/*
+ * How many physical pages per kmem arena virtual page.
+ */
+#ifndef VM_KMEM_SIZE_SCALE
+#define	VM_KMEM_SIZE_SCALE	(tsb_kernel_ldd_phys == 0 ? 3 : 2)
+#endif
+
+/*
+ * Optional floor (in bytes) on the size of the kmem arena.
+ */
+#ifndef VM_KMEM_SIZE_MIN
+#define	VM_KMEM_SIZE_MIN	(16 * 1024 * 1024)
+#endif
+
+/*
+ * Optional ceiling (in bytes) on the size of the kmem arena: 60% of the
+ * kernel map.
+ */
+#ifndef VM_KMEM_SIZE_MAX
+#define	VM_KMEM_SIZE_MAX	((VM_MAX_KERNEL_ADDRESS - \
+    VM_MIN_KERNEL_ADDRESS + 1) * 3 / 5)
+#endif
+
+/*
+ * Initial pagein size of beginning of executable file.
+ */
+#ifndef	VM_INITIAL_PAGEIN
+#define	VM_INITIAL_PAGEIN	16
+#endif
+
+#define	UMA_MD_SMALL_ALLOC
+
+extern u_int tsb_kernel_ldd_phys;
+extern vm_offset_t vm_max_kernel_address;
+
+/*
+ * Older sparc64 machines have a virtually indexed L1 data cache of 16KB.
+ * Consequently, mapping the same physical page multiple times may have
+ * caching disabled.
+ */
+#define	ZERO_REGION_SIZE	PAGE_SIZE
+
+#endif /* !_MACHINE_VMPARAM_H_ */


Property changes on: trunk/sys/sparc64/include/vmparam.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/watch.h
===================================================================
--- trunk/sys/sparc64/include/watch.h	                        (rev 0)
+++ trunk/sys/sparc64/include/watch.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,42 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2001 by Thomas Moestl <tmm at 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, 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 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/include/watch.h 113238 2003-04-08 06:35:09Z jake $
+ */
+
+#ifndef	_MACHINE_WATCH_H_
+#define	_MACHINE_WATCH_H_
+
+int	watch_phys_set_mask(vm_paddr_t pa, u_long mask);
+int	watch_phys_set(vm_paddr_t pa, int sz);
+vm_paddr_t	watch_phys_get(int *bm);
+void	watch_phys_clear(void);
+int	watch_phys_active(void);
+int	watch_virt_set_mask(vm_offset_t va, u_long mask);
+int	watch_virt_set(vm_offset_t va, int sz);
+vm_offset_t	watch_virt_get(int *bm);
+void	watch_virt_clear(void);
+int	watch_virt_active(void);
+
+#endif	/* _MACHINE_WATCH_H_ */


Property changes on: trunk/sys/sparc64/include/watch.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/include/wstate.h
===================================================================
--- trunk/sys/sparc64/include/wstate.h	                        (rev 0)
+++ trunk/sys/sparc64/include/wstate.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,67 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1997 Berkeley Software Design, Inc. 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. Berkeley Software Design Inc's name may not be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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: BSDI: wstate.h,v 1.4 1997/09/18 13:05:51 torek Exp
+ * $FreeBSD: stable/10/sys/sparc64/include/wstate.h 205409 2010-03-21 13:09:54Z marius $
+ */
+
+#ifndef	_MACHINE_WSTATE_H_
+#define	_MACHINE_WSTATE_H_
+
+/*
+ * Window state register bits
+ *
+ * There really are no bits per se, just the two fields WSTATE.NORMAL
+ * and WSTATE.OTHER.  The rest is up to software.
+ *
+ * We use WSTATE_NORMAL to represent user mode or kernel mode saves
+ * (whichever is currently in effect) and WSTATE_OTHER to represent
+ * user mode saves (only).
+ *
+ * Note that locore.s assumes this same bit layout (since the translation
+ * from "bits" to "{spill,fill}_N_{normal,other}" is done in hardware).
+ */
+
+#define	WSTATE_NORMAL_MASK	1	/* wstate normal minus transition */
+#define	WSTATE_OTHER_SHIFT	3	/* for wstate other / user */
+#define	WSTATE_OTHER_MASK		/* wstate other minus nested */ \
+	(WSTATE_NORMAL_MASK << WSTATE_OTHER_SHIFT)
+
+#define	WSTATE_KERNEL		0	/* normal kernel wstate */
+#define	WSTATE_USER_64		0	/* normal 64bit user wstate */
+#define	WSTATE_USER_32		1	/* normal 32bit user wstate */
+
+#define	WSTATE_TRANSITION	2	/* if set, force user window */
+#define	WSTATE_NESTED			/* if set, spill must not fault */ \
+	(WSTATE_TRANSITION << WSTATE_OTHER_SHIFT)
+
+/* Values used by the PROM and (Open)Solaris */
+#define	WSTATE_PROM_KMIX	7
+#define	WSTATE_PROM_MASK	7
+
+#endif /* !_MACHINE_WSTATE_H_ */


Property changes on: trunk/sys/sparc64/include/wstate.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/isa/isa.c
===================================================================
--- trunk/sys/sparc64/isa/isa.c	                        (rev 0)
+++ trunk/sys/sparc64/isa/isa.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,362 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * Copyright (c) 2001 Thomas Moestl <tmm at 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, 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.
+ *
+ *	from: FreeBSD: src/sys/alpha/isa/isa.c,v 1.26 2001/07/11
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/isa/isa.c 263763 2014-03-26 07:31:57Z dim $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+
+#include <sys/rman.h>
+
+#include <isa/isareg.h>
+#include <isa/isavar.h>
+#include <isa/isa_common.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/resource.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <sparc64/pci/ofw_pci.h>
+#include <sparc64/isa/ofw_isa.h>
+
+/* There can be only one ISA bus, so it is safe to use globals. */
+static u_int64_t isa_io_base;
+static u_int64_t isa_io_limit;
+static u_int64_t isa_mem_base;
+static u_int64_t isa_mem_limit;
+
+device_t isa_bus_device;
+
+static phandle_t isab_node;
+static struct isa_ranges *isab_ranges;
+static int isab_nrange;
+static struct ofw_bus_iinfo isa_iinfo;
+
+/*
+ * XXX: This is really partly PCI-specific, but unfortunately is
+ * differently enough to have to duplicate it here...
+ */
+#define	ISAB_RANGE_PHYS(r)						\
+	(((u_int64_t)(r)->phys_mid << 32) | (u_int64_t)(r)->phys_lo)
+#define	ISAB_RANGE_SPACE(r)	(((r)->phys_hi >> 24) & 0x03)
+
+#define	ISAR_SPACE_IO		0x01
+#define	ISAR_SPACE_MEM		0x02
+
+#define INRANGE(x, start, end)	((x) >= (start) && (x) <= (end))
+
+static void	isa_setup_children(device_t, phandle_t);
+
+void
+isa_init(device_t dev)
+{
+	device_t bridge;
+	int i;
+
+	/* The parent of the bus must be a PCI-ISA bridge. */
+	bridge = device_get_parent(dev);
+	isab_node = ofw_bus_get_node(bridge);
+	isab_nrange = OF_getprop_alloc(isab_node, "ranges",
+	    sizeof(*isab_ranges), (void **)&isab_ranges);
+	if (isab_nrange <= 0)
+		panic("isa_init: cannot get bridge range property");
+
+	ofw_bus_setup_iinfo(isab_node, &isa_iinfo, sizeof(ofw_isa_intr_t));
+
+	isa_setup_children(dev, isab_node);
+
+	for (i = isab_nrange - 1; i >= 0; i--) {
+		switch(ISAB_RANGE_SPACE(&isab_ranges[i])) {
+		case ISAR_SPACE_IO:
+			/* This is probably always 0. */
+			isa_io_base = ISAB_RANGE_PHYS(&isab_ranges[i]);
+			isa_io_limit = isab_ranges[i].size;
+			break;
+		case ISAR_SPACE_MEM:
+			/* This is probably always 0. */
+			isa_mem_base = ISAB_RANGE_PHYS(&isab_ranges[i]);
+			isa_mem_limit = isab_ranges[i].size;
+			break;
+		}
+	}
+}
+
+static const struct {
+	const char	*const name;
+	uint32_t	id;
+} ofw_isa_pnp_map[] = {
+	{ "SUNW,lomh",	0x0000ae4e }, /* SUN0000 */
+	{ "dma",	0x0002d041 }, /* PNP0200 */
+	{ "floppy",	0x0007d041 }, /* PNP0700 */
+	{ "rtc",	0x000bd041 }, /* PNP0B00 */
+	{ "flashprom",	0x0100ae4e }, /* SUN0001 */
+	{ "parallel",	0x0104d041 }, /* PNP0401 */
+	{ "serial",	0x0105d041 }, /* PNP0501 */
+	{ "su",		0x0105d041 }, /* PNP0501 */
+	{ "i2c",	0x0200ae4e }, /* SUN0002 */
+	{ "rmc-comm",	0x0300ae4e }, /* SUN0003 */
+	{ "kb_ps2",	0x0303d041 }, /* PNP0303 */
+	{ "kdmouse",	0x030fd041 }, /* PNP0F03 */
+	{ "bscbus",	0x0400ae4e }, /* SUN0004 */
+	{ "power",	0x0c0cd041 }, /* PNP0C0C */
+	{ NULL,		0x0 }
+};
+
+static void
+isa_setup_children(device_t dev, phandle_t parent)
+{
+	struct isa_regs *regs;
+	struct resource_list *rl;
+	device_t cdev;
+	u_int64_t end, start;
+	ofw_isa_intr_t *intrs, rintr;
+	phandle_t node;
+	uint32_t *drqs, *regidx;
+	int i, ndrq, nintr, nreg, nregidx, rid, rtype;
+	char *name;
+
+	/*
+	 * Loop through children and fake up PnP devices for them.
+	 * Their resources are added as fully mapped and specified because
+	 * adjusting the resources and the resource list entries respectively
+	 * in isa_alloc_resource() causes trouble with drivers which use
+	 * rman_get_start(), pass-through or allocate and release resources
+	 * multiple times, etc. Adjusting the resources might be better off
+	 * in a bus_activate_resource method but the common ISA code doesn't
+	 * allow for an isa_activate_resource().
+	 */
+	for (node = OF_child(parent); node != 0; node = OF_peer(node)) {
+		if ((OF_getprop_alloc(node, "name", 1, (void **)&name)) == -1)
+			continue;
+
+		/*
+		 * Keyboard and mouse controllers hang off of the `8042'
+		 * node but we have no real use for the `8042' itself.
+		 */
+		if (strcmp(name, "8042") == 0) {
+			isa_setup_children(dev, node);
+			free(name, M_OFWPROP);
+			continue;
+		}
+
+		for (i = 0; ofw_isa_pnp_map[i].name != NULL; i++)
+			if (strcmp(ofw_isa_pnp_map[i].name, name) == 0)
+				break;
+		if (ofw_isa_pnp_map[i].name == NULL) {
+			device_printf(dev, "no PnP map entry for node "
+			    "0x%lx: %s\n", (unsigned long)node, name);
+			free(name, M_OFWPROP);
+			continue;
+		}
+
+		if ((cdev = BUS_ADD_CHILD(dev, ISA_ORDER_PNPBIOS, NULL, -1)) ==
+		    NULL)
+			panic("isa_setup_children: BUS_ADD_CHILD failed");
+		isa_set_logicalid(cdev, ofw_isa_pnp_map[i].id);
+		isa_set_vendorid(cdev, ofw_isa_pnp_map[i].id);
+
+		rl = BUS_GET_RESOURCE_LIST(dev, cdev);
+		nreg = OF_getprop_alloc(node, "reg", sizeof(*regs),
+		    (void **)&regs);
+		for (i = 0; i < nreg; i++) {
+			start = ISA_REG_PHYS(&regs[i]);
+			end = start + regs[i].size - 1;
+			rtype = ofw_isa_range_map(isab_ranges, isab_nrange,
+			    &start, &end, NULL);
+			rid = 0;
+			while (resource_list_find(rl, rtype, rid) != NULL)
+				rid++;
+			bus_set_resource(cdev, rtype, rid, start,
+			    end - start + 1);
+		}
+		if (nreg == -1 && parent != isab_node) {
+			/*
+			 * The "reg" property still might be an index into
+			 * the set of registers of the parent device like
+			 * with the nodes hanging off of the `8042' node.
+			 */
+			nregidx = OF_getprop_alloc(node, "reg", sizeof(*regidx),
+			    (void **)&regidx);
+			if (nregidx > 2)
+				panic("isa_setup_children: impossible number "
+				    "of register indices");
+			if (nregidx != -1 && (nreg = OF_getprop_alloc(parent,
+			    "reg", sizeof(*regs), (void **)&regs)) >= nregidx) {
+				for (i = 0; i < nregidx; i++) {
+					start = ISA_REG_PHYS(&regs[regidx[i]]);
+					end = start + regs[regidx[i]].size - 1;
+					rtype = ofw_isa_range_map(isab_ranges,
+					    isab_nrange, &start, &end, NULL);
+					rid = 0;
+					while (resource_list_find(rl, rtype,
+					    rid) != NULL)
+						rid++;
+					bus_set_resource(cdev, rtype, rid,
+					    start, end - start + 1);
+				}
+			}
+			if (regidx != NULL)
+				free(regidx, M_OFWPROP);
+		}
+		if (regs != NULL)
+			free(regs, M_OFWPROP);
+
+		nintr = OF_getprop_alloc(node, "interrupts", sizeof(*intrs),
+		    (void **)&intrs);
+		for (i = 0; i < nintr; i++) {
+			if (intrs[i] > 7)
+				panic("isa_setup_children: intr too large");
+			rintr = ofw_isa_route_intr(device_get_parent(dev), node,
+			    &isa_iinfo, intrs[i]);
+			if (rintr == PCI_INVALID_IRQ) {
+				device_printf(dev, "could not map ISA "
+				    "interrupt %d for node 0x%lx: %s\n",
+				    intrs[i], (unsigned long)node, name);
+				continue;
+			}
+			bus_set_resource(cdev, SYS_RES_IRQ, i, rintr, 1);
+		}
+		if (intrs != NULL)
+			free(intrs, M_OFWPROP);
+
+		ndrq = OF_getprop_alloc(node, "dma-channel", sizeof(*drqs),
+		    (void **)&drqs);
+		for (i = 0; i < ndrq; i++)
+			bus_set_resource(cdev, SYS_RES_DRQ, i, drqs[i], 1);
+		if (drqs != NULL)
+			free(drqs, M_OFWPROP);
+
+		/*
+		 * Devices using DMA hang off of the `dma' node instead of
+		 * directly from the ISA bridge node.
+		 */
+		if (strcmp(name, "dma") == 0)
+			isa_setup_children(dev, node);
+
+		free(name, M_OFWPROP);
+	}
+}
+
+struct resource *
+isa_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	/*
+	 * Consider adding a resource definition.
+	 */
+	int passthrough = (device_get_parent(child) != bus);
+	int isdefault = (start == 0UL && end == ~0UL);
+	struct resource_list *rl;
+	struct resource_list_entry *rle;
+	u_long base, limit;
+
+	rl = BUS_GET_RESOURCE_LIST(bus, child);
+	if (!passthrough && !isdefault) {
+		rle = resource_list_find(rl, type, *rid);
+		if (!rle) {
+			if (*rid < 0)
+				return (NULL);
+			switch (type) {
+			case SYS_RES_IRQ:
+				if (*rid >= ISA_NIRQ)
+					return (NULL);
+				break;
+			case SYS_RES_DRQ:
+				if (*rid >= ISA_NDRQ)
+					return (NULL);
+				break;
+			case SYS_RES_MEMORY:
+				if (*rid >= ISA_NMEM)
+					return (NULL);
+				break;
+			case SYS_RES_IOPORT:
+				if (*rid >= ISA_NPORT)
+					return (NULL);
+				break;
+			default:
+				return (NULL);
+			}
+			resource_list_add(rl, type, *rid, start, end, count);
+		}
+	}
+
+	/*
+	 * Sanity check if the resource in the respective entry is fully
+	 * mapped and specified and its type allocable. A driver could
+	 * have added an out of range resource on its own.
+	 */
+	if (!passthrough) {
+		if ((rle = resource_list_find(rl, type, *rid)) == NULL)
+			return (NULL);
+		base = limit = 0;
+		switch (type) {
+		case SYS_RES_MEMORY:
+			base = isa_mem_base;
+			limit = base + isa_mem_limit;
+			break;
+		case SYS_RES_IOPORT:
+			base = isa_io_base;
+			limit = base + isa_io_limit;
+			break;
+		case SYS_RES_IRQ:
+			if (rle->start != rle->end || rle->start <= 7)
+				return (NULL);
+			break;
+		case SYS_RES_DRQ:
+			break;
+		default:
+			return (NULL);
+		}
+		if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+			if (!INRANGE(rle->start, base, limit) ||
+			    !INRANGE(rle->end, base, limit))
+				return (NULL);
+		}
+	}
+
+	return (resource_list_alloc(rl, bus, child, type, rid, start, end,
+	    count, flags));
+}
+
+int
+isa_release_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *res)
+{
+
+	return (bus_generic_rl_release_resource(bus, child, type, rid, res));
+}


Property changes on: trunk/sys/sparc64/isa/isa.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/isa/isa_dma.c
===================================================================
--- trunk/sys/sparc64/isa/isa_dma.c	                        (rev 0)
+++ trunk/sys/sparc64/isa/isa_dma.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,97 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Pyun YongHyeon.
+ * 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.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/isa/isa_dma.c 141391 2005-02-06 13:46:39Z phk $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <isa/isareg.h>
+#include <isa/isavar.h>
+
+/*
+ * Glue code to load sound(4). Though fdc(4), ppc(4) don't work on
+ * sparc64 yet, they may need this glue code too.
+ */
+
+int
+isa_dma_init(int chan, u_int bouncebufsize, int flag)
+{
+
+	return (0);
+}
+
+int
+isa_dma_acquire(int chan)
+{
+	return (0);
+}
+
+void
+isa_dma_release(int chan)
+{
+
+}
+
+void
+isa_dmacascade(int chan)
+{
+
+}
+
+void
+isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
+{
+
+}
+
+void
+isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
+{
+
+}
+
+int
+isa_dmastatus(int chan)
+{
+	return (0);
+}
+
+int
+isa_dmatc(int chan)
+{
+	return (0);
+}
+
+int
+isa_dmastop(int chan)
+{
+	return (0);
+}


Property changes on: trunk/sys/sparc64/isa/isa_dma.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/isa/ofw_isa.c
===================================================================
--- trunk/sys/sparc64/isa/ofw_isa.c	                        (rev 0)
+++ trunk/sys/sparc64/isa/ofw_isa.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,147 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: ebus.c,v 1.52 2008/05/29 14:51:26 mrg Exp
+ */
+/*-
+ * Copyright (c) 2001, 2003 Thomas Moestl <tmm at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/isa/ofw_isa.c 266020 2014-05-14 14:17:51Z ian $");
+
+/*
+ * Helper functions which can be used in both ISA and EBus code.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <sparc64/pci/ofw_pci.h>
+#include <sparc64/isa/ofw_isa.h>
+
+#include "pcib_if.h"
+
+int
+ofw_isa_range_restype(struct isa_ranges *range)
+{
+	int ps = ISA_RANGE_PS(range);
+
+	switch (ps) {
+	case OFW_PCI_CS_IO:
+		return (SYS_RES_IOPORT);
+	case OFW_PCI_CS_MEM32:
+		return (SYS_RES_MEMORY);
+	default:
+		panic("ofw_isa_range_restype: illegal space %x", ps);
+	}
+
+}
+
+/* XXX: this only supports PCI as parent bus right now. */
+int
+ofw_isa_range_map(struct isa_ranges *range, int nrange, u_long *start,
+    u_long *end, int *which)
+{
+	struct isa_ranges *r;
+	uint64_t offs, cstart, cend;
+	int i;
+
+	for (i = 0; i < nrange; i++) {
+		r = &range[i];
+		cstart = ISA_RANGE_CHILD(r);
+		cend = cstart + r->size - 1;
+		if (*start < cstart || *start > cend)
+			continue;
+		if (*end < cstart || *end > cend) {
+			panic("ofw_isa_map_iorange: iorange crosses PCI "
+			    "ranges (%#lx not in %#lx - %#lx)", *end, cstart,
+			    cend);
+		}
+		offs = ISA_RANGE_PHYS(r);
+		*start = *start + offs - cstart;
+		*end  = *end + offs - cstart;
+		if (which != NULL)
+			*which = i;
+		return (ofw_isa_range_restype(r));
+	}
+	panic("ofw_isa_map_iorange: could not map range %#lx - %#lx",
+	    *start, *end);
+}
+
+ofw_pci_intr_t
+ofw_isa_route_intr(device_t bridge, phandle_t node, struct ofw_bus_iinfo *ii,
+    ofw_isa_intr_t intr)
+{
+	struct isa_regs reg;
+	device_t pbridge;
+	ofw_isa_intr_t mintr;
+
+	pbridge = device_get_parent(device_get_parent(bridge));
+	/*
+	 * If we get a match from using the map, the resulting INO is
+	 * fully specified, so we may not continue to map.
+	 */
+	if (!ofw_bus_lookup_imap(node, ii, &reg, sizeof(reg),
+	    &intr, sizeof(intr), &mintr, sizeof(mintr), NULL)) {
+		/* Try routing at the parent bridge. */
+		mintr = PCIB_ROUTE_INTERRUPT(pbridge, bridge, intr);
+	}
+	return (mintr);
+}


Property changes on: trunk/sys/sparc64/isa/ofw_isa.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/isa/ofw_isa.h
===================================================================
--- trunk/sys/sparc64/isa/ofw_isa.h	                        (rev 0)
+++ trunk/sys/sparc64/isa/ofw_isa.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,101 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: ebus.c,v 1.52 2008/05/29 14:51:26 mrg Exp
+ */
+/*-
+ * Copyright (c) 2001 Thomas Moestl <tmm at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/isa/ofw_isa.h 219567 2011-03-12 14:33:32Z marius $
+ */
+
+#ifndef _SPARC64_ISA_OFW_ISA_H_
+#define _SPARC64_ISA_OFW_ISA_H_
+
+/*
+ * ISA PROM structures
+ */
+struct isa_regs {
+	u_int32_t	phys_hi;	/* high bits of physaddr */ 
+	u_int32_t	phys_lo;
+	u_int32_t	size;
+};
+
+#define	ISA_REG_PHYS(r) \
+	((((u_int64_t)((r)->phys_hi)) << 32) | ((u_int64_t)(r)->phys_lo))
+
+/* XXX: this is a guess. Verify... */
+struct isa_ranges {
+	u_int32_t	child_hi;
+	u_int32_t	child_lo;
+	u_int32_t	phys_hi;
+	u_int32_t	phys_mid;
+	u_int32_t	phys_lo;
+	u_int32_t	size;
+};
+
+#define	ISA_RANGE_CHILD(r) \
+	((((u_int64_t)((r)->child_hi)) << 32) | ((u_int64_t)(r)->child_lo))
+#define	ISA_RANGE_PS(r)	(((r)->phys_hi >> 24) & 0x03)
+#define	ISA_RANGE_PHYS(r) \
+	((((u_int64_t)(r)->phys_mid) << 32) | ((u_int64_t)(r)->phys_lo))
+
+typedef u_int32_t ofw_isa_intr_t;
+
+int ofw_isa_range_restype(struct isa_ranges *);
+/* Map an IO range. Returns the resource type of the range. */
+int ofw_isa_range_map(struct isa_ranges *, int, u_long *, u_long *, int *);
+
+ofw_pci_intr_t ofw_isa_route_intr(device_t, phandle_t, struct ofw_bus_iinfo *,
+    ofw_isa_intr_t);
+
+#endif /* !_SPARC64_ISA_OFW_ISA_H_ */


Property changes on: trunk/sys/sparc64/isa/ofw_isa.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/apb.c
===================================================================
--- trunk/sys/sparc64/pci/apb.c	                        (rev 0)
+++ trunk/sys/sparc64/pci/apb.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,307 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1994,1995 Stefan Esser, Wolfgang StanglMeier
+ * Copyright (c) 2000 Michael Smith <msmith at freebsd.org>
+ * Copyright (c) 2000 BSDi
+ * Copyright (c) 2001, 2003 Thomas Moestl <tmm at 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, 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.
+ *
+ *	from: FreeBSD: src/sys/dev/pci/pci_pci.c,v 1.3 2000/12/13
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/pci/apb.c 284455 2015-06-16 18:39:11Z emaste $");
+
+/*
+ * Support for the Sun APB (Advanced PCI Bridge) PCI-PCI bridge.
+ * This bridge does not fully comply to the PCI bridge specification, and is
+ * therefore not supported by the generic driver.
+ * We can use some of the pcib methods anyway.
+ */
+
+#include "opt_ofw_pci.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcib_private.h>
+
+#include "pcib_if.h"
+
+#include <sparc64/pci/ofw_pci.h>
+#include <sparc64/pci/ofw_pcib_subr.h>
+
+/*
+ * Bridge-specific data.
+ */
+struct apb_softc {
+	struct ofw_pcib_gen_softc	sc_bsc;
+	uint8_t		sc_iomap;
+	uint8_t		sc_memmap;
+};
+
+static device_probe_t apb_probe;
+static device_attach_t apb_attach;
+static bus_alloc_resource_t apb_alloc_resource;
+static bus_adjust_resource_t apb_adjust_resource;
+
+static device_method_t apb_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		apb_probe),
+	DEVMETHOD(device_attach,	apb_attach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_alloc_resource,	apb_alloc_resource),
+	DEVMETHOD(bus_adjust_resource,	apb_adjust_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+
+	/* pcib interface */
+	DEVMETHOD(pcib_route_interrupt,	ofw_pcib_gen_route_interrupt),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_node,	ofw_pcib_gen_get_node),
+
+	DEVMETHOD_END
+};
+
+static devclass_t pcib_devclass;
+
+DEFINE_CLASS_1(pcib, apb_driver, apb_methods, sizeof(struct apb_softc),
+    pcib_driver);
+EARLY_DRIVER_MODULE(apb, pci, apb_driver, pcib_devclass, 0, 0, BUS_PASS_BUS);
+MODULE_DEPEND(apb, pci, 1, 1, 1);
+
+/* APB specific registers */
+#define	APBR_IOMAP	0xde
+#define	APBR_MEMMAP	0xdf
+
+/* Definitions for the mapping registers */
+#define	APB_IO_SCALE	0x200000
+#define	APB_MEM_SCALE	0x20000000
+
+/*
+ * Generic device interface
+ */
+static int
+apb_probe(device_t dev)
+{
+
+	if (pci_get_vendor(dev) == 0x108e &&	/* Sun */
+	    pci_get_device(dev) == 0x5000)  {	/* APB */
+		device_set_desc(dev, "APB PCI-PCI bridge");
+		return (0);
+	}
+	return (ENXIO);
+}
+
+static void
+apb_map_print(uint8_t map, u_long scale)
+{
+	int i, first;
+
+	for (first = 1, i = 0; i < 8; i++) {
+		if ((map & (1 << i)) != 0) {
+			printf("%s0x%lx-0x%lx", first ? "" : ", ",
+			    i * scale, (i + 1) * scale - 1);
+			first = 0;
+		}
+	}
+}
+
+static int
+apb_checkrange(uint8_t map, u_long scale, u_long start, u_long end)
+{
+	int i, ei;
+
+	i = start / scale;
+	ei = end / scale;
+	if (i > 7 || ei > 7)
+		return (0);
+	for (; i <= ei; i++)
+		if ((map & (1 << i)) == 0)
+			return (0);
+	return (1);
+}
+
+static int
+apb_attach(device_t dev)
+{
+	struct apb_softc *sc;
+	struct sysctl_ctx_list *sctx;
+	struct sysctl_oid *soid;
+
+	sc = device_get_softc(dev);
+
+	/*
+	 * Get current bridge configuration.
+	 */
+	sc->sc_bsc.ops_pcib_sc.domain = pci_get_domain(dev);
+	sc->sc_bsc.ops_pcib_sc.pribus = pci_get_bus(dev);
+	pci_write_config(dev, PCIR_PRIBUS_1, sc->sc_bsc.ops_pcib_sc.pribus, 1);
+	sc->sc_bsc.ops_pcib_sc.bus.sec =
+	    pci_read_config(dev, PCIR_SECBUS_1, 1);
+	sc->sc_bsc.ops_pcib_sc.bus.sub =
+	    pci_read_config(dev, PCIR_SUBBUS_1, 1);
+	sc->sc_bsc.ops_pcib_sc.bridgectl =
+	    pci_read_config(dev, PCIR_BRIDGECTL_1, 2);
+	sc->sc_iomap = pci_read_config(dev, APBR_IOMAP, 1);
+	sc->sc_memmap = pci_read_config(dev, APBR_MEMMAP, 1);
+
+	/*
+	 * Setup SYSCTL reporting nodes.
+	 */
+	sctx = device_get_sysctl_ctx(dev);
+	soid = device_get_sysctl_tree(dev);
+	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "domain",
+	    CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.domain, 0,
+	    "Domain number");
+	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "pribus",
+	    CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.pribus, 0,
+	    "Primary bus number");
+	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "secbus",
+	    CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.bus.sec, 0,
+	    "Secondary bus number");
+	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "subbus",
+	    CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.bus.sub, 0,
+	    "Subordinate bus number");
+
+	ofw_pcib_gen_setup(dev);
+
+	if (bootverbose) {
+		device_printf(dev, "  domain            %d\n",
+		    sc->sc_bsc.ops_pcib_sc.domain);
+		device_printf(dev, "  secondary bus     %d\n",
+		    sc->sc_bsc.ops_pcib_sc.bus.sec);
+		device_printf(dev, "  subordinate bus   %d\n",
+		    sc->sc_bsc.ops_pcib_sc.bus.sub);
+		device_printf(dev, "  I/O decode        ");
+		apb_map_print(sc->sc_iomap, APB_IO_SCALE);
+		printf("\n");
+		device_printf(dev, "  memory decode     ");
+		apb_map_print(sc->sc_memmap, APB_MEM_SCALE);
+		printf("\n");
+	}
+
+	device_add_child(dev, "pci", -1);
+	return (bus_generic_attach(dev));
+}
+
+/*
+ * We have to trap resource allocation requests and ensure that the bridge
+ * is set up to, or capable of handling them.
+ */
+static struct resource *
+apb_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct apb_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	/*
+	 * If this is a "default" allocation against this rid, we can't work
+	 * out where it's coming from (we should actually never see these) so
+	 * we just have to punt.
+	 */
+	if (start == 0 && end == ~0) {
+		device_printf(dev, "can't decode default resource id %d for "
+		    "%s, bypassing\n", *rid, device_get_nameunit(child));
+		goto passup;
+	}
+
+	/*
+	 * Fail the allocation for this range if it's not supported.
+	 * XXX we should probably just fix up the bridge decode and
+	 * soldier on.
+	 */
+	switch (type) {
+	case SYS_RES_IOPORT:
+		if (!apb_checkrange(sc->sc_iomap, APB_IO_SCALE, start, end)) {
+			device_printf(dev, "device %s requested unsupported "
+			    "I/O range 0x%lx-0x%lx\n",
+			    device_get_nameunit(child), start, end);
+			return (NULL);
+		}
+		if (bootverbose)
+			device_printf(sc->sc_bsc.ops_pcib_sc.dev, "device "
+			    "%s requested decoded I/O range 0x%lx-0x%lx\n",
+			    device_get_nameunit(child), start, end);
+		break;
+	case SYS_RES_MEMORY:
+		if (!apb_checkrange(sc->sc_memmap, APB_MEM_SCALE, start,
+		    end)) {
+			device_printf(dev, "device %s requested unsupported "
+			    "memory range 0x%lx-0x%lx\n",
+			    device_get_nameunit(child), start, end);
+			return (NULL);
+		}
+		if (bootverbose)
+			device_printf(sc->sc_bsc.ops_pcib_sc.dev, "device "
+			    "%s requested decoded memory range 0x%lx-0x%lx\n",
+			    device_get_nameunit(child), start, end);
+		break;
+	}
+
+ passup:
+	/*
+	 * Bridge is OK decoding this resource, so pass it up.
+	 */
+	return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
+	    count, flags));
+}
+
+static int
+apb_adjust_resource(device_t dev, device_t child, int type,
+    struct resource *r, u_long start, u_long end)
+{
+	struct apb_softc *sc;
+
+	sc = device_get_softc(dev);
+	switch (type) {
+	case SYS_RES_IOPORT:
+		if (!apb_checkrange(sc->sc_iomap, APB_IO_SCALE, start, end))
+			return (ENXIO);
+		break;
+	case SYS_RES_MEMORY:
+		if (!apb_checkrange(sc->sc_memmap, APB_MEM_SCALE, start, end))
+			return (ENXIO);
+		break;
+	}
+	return (bus_generic_adjust_resource(dev, child, type, r, start, end));
+}


Property changes on: trunk/sys/sparc64/pci/apb.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/fire.c
===================================================================
--- trunk/sys/sparc64/pci/fire.c	                        (rev 0)
+++ trunk/sys/sparc64/pci/fire.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,1875 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm at FreeBSD.org>
+ * Copyright (c) 2009 by Marius Strobl <marius at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp
+ *	from: FreeBSD: psycho.c 183152 2008-09-18 19:45:22Z marius
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/pci/fire.c 305615 2016-09-08 15:06:28Z pfg $");
+
+/*
+ * Driver for `Fire' JBus to PCI Express and `Oberon' Uranus to PCI Express
+ * bridges
+ */
+
+#include "opt_fire.h"
+#include "opt_ofw_pci.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/pciio.h>
+#include <sys/pcpu.h>
+#include <sys/rman.h>
+#include <sys/smp.h>
+#include <sys/sysctl.h>
+#include <sys/timetc.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/openfirm.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/bus_common.h>
+#include <machine/bus_private.h>
+#include <machine/iommureg.h>
+#include <machine/iommuvar.h>
+#include <machine/pmap.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <sparc64/pci/ofw_pci.h>
+#include <sparc64/pci/firereg.h>
+#include <sparc64/pci/firevar.h>
+
+#include "pcib_if.h"
+
+struct fire_msiqarg;
+
+static const struct fire_desc *fire_get_desc(device_t dev);
+static void fire_dmamap_sync(bus_dma_tag_t dt __unused, bus_dmamap_t map,
+    bus_dmasync_op_t op);
+static int fire_get_intrmap(struct fire_softc *sc, u_int ino,
+    bus_addr_t *intrmapptr, bus_addr_t *intrclrptr);
+static void fire_intr_assign(void *arg);
+static void fire_intr_clear(void *arg);
+static void fire_intr_disable(void *arg);
+static void fire_intr_enable(void *arg);
+static int fire_intr_register(struct fire_softc *sc, u_int ino);
+static inline void fire_msiq_common(struct intr_vector *iv,
+    struct fire_msiqarg *fmqa);
+static void fire_msiq_filter(void *cookie);
+static void fire_msiq_handler(void *cookie);
+static void fire_set_intr(struct fire_softc *sc, u_int index, u_int ino,
+    driver_filter_t handler, void *arg);
+static timecounter_get_t fire_get_timecount;
+
+/* Interrupt handlers */
+static driver_filter_t fire_dmc_pec;
+static driver_filter_t fire_pcie;
+static driver_filter_t fire_xcb;
+
+/*
+ * Methods
+ */
+static pcib_alloc_msi_t fire_alloc_msi;
+static pcib_alloc_msix_t fire_alloc_msix;
+static bus_alloc_resource_t fire_alloc_resource;
+static device_attach_t fire_attach;
+static pcib_map_msi_t fire_map_msi;
+static pcib_maxslots_t fire_maxslots;
+static device_probe_t fire_probe;
+static pcib_read_config_t fire_read_config;
+static pcib_release_msi_t fire_release_msi;
+static pcib_release_msix_t fire_release_msix;
+static pcib_route_interrupt_t fire_route_interrupt;
+static bus_setup_intr_t fire_setup_intr;
+static bus_teardown_intr_t fire_teardown_intr;
+static pcib_write_config_t fire_write_config;
+
+static device_method_t fire_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		fire_probe),
+	DEVMETHOD(device_attach,	fire_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	ofw_pci_read_ivar),
+	DEVMETHOD(bus_setup_intr,	fire_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	fire_teardown_intr),
+	DEVMETHOD(bus_alloc_resource,	fire_alloc_resource),
+	DEVMETHOD(bus_activate_resource, ofw_pci_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	ofw_pci_adjust_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+	DEVMETHOD(bus_get_dma_tag,	ofw_pci_get_dma_tag),
+
+	/* pcib interface */
+	DEVMETHOD(pcib_maxslots,	fire_maxslots),
+	DEVMETHOD(pcib_read_config,	fire_read_config),
+	DEVMETHOD(pcib_write_config,	fire_write_config),
+	DEVMETHOD(pcib_route_interrupt,	fire_route_interrupt),
+	DEVMETHOD(pcib_alloc_msi,	fire_alloc_msi),
+	DEVMETHOD(pcib_release_msi,	fire_release_msi),
+	DEVMETHOD(pcib_alloc_msix,	fire_alloc_msix),
+	DEVMETHOD(pcib_release_msix,	fire_release_msix),
+	DEVMETHOD(pcib_map_msi,		fire_map_msi),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_node,	ofw_pci_get_node),
+
+	DEVMETHOD_END
+};
+
+static devclass_t fire_devclass;
+
+DEFINE_CLASS_0(pcib, fire_driver, fire_methods, sizeof(struct fire_softc));
+EARLY_DRIVER_MODULE(fire, nexus, fire_driver, fire_devclass, 0, 0,
+    BUS_PASS_BUS);
+MODULE_DEPEND(fire, nexus, 1, 1, 1);
+
+static const struct intr_controller fire_ic = {
+	fire_intr_enable,
+	fire_intr_disable,
+	fire_intr_assign,
+	fire_intr_clear
+};
+
+struct fire_icarg {
+	struct fire_softc	*fica_sc;
+	bus_addr_t		fica_map;
+	bus_addr_t		fica_clr;
+};
+
+static const struct intr_controller fire_msiqc_filter = {
+	fire_intr_enable,
+	fire_intr_disable,
+	fire_intr_assign,
+	NULL
+};
+
+struct fire_msiqarg {
+	struct fire_icarg	fmqa_fica;
+	struct mtx		fmqa_mtx;
+	struct fo_msiq_record	*fmqa_base;
+	uint64_t		fmqa_head;
+	uint64_t		fmqa_tail;
+	uint32_t		fmqa_msiq;
+	uint32_t		fmqa_msi;
+};
+
+#define	FIRE_PERF_CNT_QLTY	100
+
+#define	FIRE_SPC_BARRIER(spc, sc, offs, len, flags)			\
+	bus_barrier((sc)->sc_mem_res[(spc)], (offs), (len), (flags))
+#define	FIRE_SPC_READ_8(spc, sc, offs)					\
+	bus_read_8((sc)->sc_mem_res[(spc)], (offs))
+#define	FIRE_SPC_WRITE_8(spc, sc, offs, v)				\
+	bus_write_8((sc)->sc_mem_res[(spc)], (offs), (v))
+
+#ifndef FIRE_DEBUG
+#define	FIRE_SPC_SET(spc, sc, offs, reg, v)				\
+	FIRE_SPC_WRITE_8((spc), (sc), (offs), (v))
+#else
+#define	FIRE_SPC_SET(spc, sc, offs, reg, v) do {			\
+	device_printf((sc)->sc_dev, reg " 0x%016llx -> 0x%016llx\n",	\
+	    (unsigned long long)FIRE_SPC_READ_8((spc), (sc), (offs)),	\
+	    (unsigned long long)(v));					\
+	FIRE_SPC_WRITE_8((spc), (sc), (offs), (v));			\
+	} while (0)
+#endif
+
+#define	FIRE_PCI_BARRIER(sc, offs, len, flags)				\
+	FIRE_SPC_BARRIER(FIRE_PCI, (sc), (offs), len, flags)
+#define	FIRE_PCI_READ_8(sc, offs)					\
+	FIRE_SPC_READ_8(FIRE_PCI, (sc), (offs))
+#define	FIRE_PCI_WRITE_8(sc, offs, v)					\
+	FIRE_SPC_WRITE_8(FIRE_PCI, (sc), (offs), (v))
+#define	FIRE_CTRL_BARRIER(sc, offs, len, flags)				\
+	FIRE_SPC_BARRIER(FIRE_CTRL, (sc), (offs), len, flags)
+#define	FIRE_CTRL_READ_8(sc, offs)					\
+	FIRE_SPC_READ_8(FIRE_CTRL, (sc), (offs))
+#define	FIRE_CTRL_WRITE_8(sc, offs, v)					\
+	FIRE_SPC_WRITE_8(FIRE_CTRL, (sc), (offs), (v))
+
+#define	FIRE_PCI_SET(sc, offs, v)					\
+	FIRE_SPC_SET(FIRE_PCI, (sc), (offs), # offs, (v))
+#define	FIRE_CTRL_SET(sc, offs, v)					\
+	FIRE_SPC_SET(FIRE_CTRL, (sc), (offs), # offs, (v))
+
+struct fire_desc {
+	const char	*fd_string;
+	int		fd_mode;
+	const char	*fd_name;
+};
+
+static const struct fire_desc fire_compats[] = {
+	{ "pciex108e,80f0",	FIRE_MODE_FIRE,		"Fire" },
+#if 0
+	{ "pciex108e,80f8",	FIRE_MODE_OBERON,	"Oberon" },
+#endif
+	{ NULL,			0,			NULL }
+};
+
+static const struct fire_desc *
+fire_get_desc(device_t dev)
+{
+	const struct fire_desc *desc;
+	const char *compat;
+
+	compat = ofw_bus_get_compat(dev);
+	if (compat == NULL)
+		return (NULL);
+	for (desc = fire_compats; desc->fd_string != NULL; desc++)
+		if (strcmp(desc->fd_string, compat) == 0)
+			return (desc);
+	return (NULL);
+}
+
+static int
+fire_probe(device_t dev)
+{
+	const char *dtype;
+
+	dtype = ofw_bus_get_type(dev);
+	if (dtype != NULL && strcmp(dtype, OFW_TYPE_PCIE) == 0 &&
+	    fire_get_desc(dev) != NULL) {
+		device_set_desc(dev, "Sun Host-PCIe bridge");
+		return (BUS_PROBE_GENERIC);
+	}
+	return (ENXIO);
+}
+
+static int
+fire_attach(device_t dev)
+{
+	struct fire_softc *sc;
+	const struct fire_desc *desc;
+	struct ofw_pci_msi_ranges msi_ranges;
+	struct ofw_pci_msi_addr_ranges msi_addr_ranges;
+	struct ofw_pci_msi_eq_to_devino msi_eq_to_devino;
+	struct fire_msiqarg *fmqa;
+	struct timecounter *tc;
+	bus_dma_tag_t dmat;
+	uint64_t ino_bitmap, val;
+	phandle_t node;
+	uint32_t prop, prop_array[2];
+	int i, j, mode;
+	u_int lw;
+	uint16_t mps;
+
+	sc = device_get_softc(dev);
+	node = ofw_bus_get_node(dev);
+	desc = fire_get_desc(dev);
+	mode = desc->fd_mode;
+
+	sc->sc_dev = dev;
+	sc->sc_mode = mode;
+	sc->sc_flags = 0;
+
+	mtx_init(&sc->sc_msi_mtx, "msi_mtx", NULL, MTX_DEF);
+	mtx_init(&sc->sc_pcib_mtx, "pcib_mtx", NULL, MTX_SPIN);
+
+	/*
+	 * Fire and Oberon have two register banks:
+	 * (0) per-PBM PCI Express configuration and status registers
+	 * (1) (shared) Fire/Oberon controller configuration and status
+	 *     registers
+	 */
+	for (i = 0; i < FIRE_NREG; i++) {
+		j = i;
+		sc->sc_mem_res[i] = bus_alloc_resource_any(dev,
+		    SYS_RES_MEMORY, &j, RF_ACTIVE);
+		if (sc->sc_mem_res[i] == NULL)
+			panic("%s: could not allocate register bank %d",
+			    __func__, i);
+	}
+
+	if (OF_getprop(node, "portid", &sc->sc_ign, sizeof(sc->sc_ign)) == -1)
+		panic("%s: could not determine IGN", __func__);
+	if (OF_getprop(node, "module-revision#", &prop, sizeof(prop)) == -1)
+		panic("%s: could not determine module-revision", __func__);
+
+	device_printf(dev, "%s, module-revision %d, IGN %#x\n",
+	    desc->fd_name, prop, sc->sc_ign);
+
+	/*
+	 * Hunt through all the interrupt mapping regs and register
+	 * the interrupt controller for our interrupt vectors.  We do
+	 * this early in order to be able to catch stray interrupts.
+	 */
+	i = OF_getprop(node, "ino-bitmap", (void *)prop_array,
+	    sizeof(prop_array));
+	if (i == -1)
+		panic("%s: could not get ino-bitmap", __func__);
+	ino_bitmap = ((uint64_t)prop_array[1] << 32) | prop_array[0];
+	for (i = 0; i <= FO_MAX_INO; i++) {
+		if ((ino_bitmap & (1ULL << i)) == 0)
+			continue;
+		j = fire_intr_register(sc, i);
+		if (j != 0)
+			device_printf(dev, "could not register interrupt "
+			    "controller for INO %d (%d)\n", i, j);
+	}
+
+	/* JBC/UBC module initialization */
+	FIRE_CTRL_SET(sc, FO_XBC_ERR_LOG_EN, ~0ULL);
+	FIRE_CTRL_SET(sc, FO_XBC_ERR_STAT_CLR, ~0ULL);
+	/* not enabled by OpenSolaris */
+	FIRE_CTRL_SET(sc, FO_XBC_INT_EN, ~0ULL);
+	if (sc->sc_mode == FIRE_MODE_FIRE) {
+		FIRE_CTRL_SET(sc, FIRE_JBUS_PAR_CTRL,
+		    FIRE_JBUS_PAR_CTRL_P_EN);
+		FIRE_CTRL_SET(sc, FIRE_JBC_FATAL_RST_EN,
+		    ((1ULL << FIRE_JBC_FATAL_RST_EN_SPARE_P_INT_SHFT) &
+		    FIRE_JBC_FATAL_RST_EN_SPARE_P_INT_MASK) |
+		    FIRE_JBC_FATAL_RST_EN_MB_PEA_P_INT |
+		    FIRE_JBC_FATAL_RST_EN_CPE_P_INT |
+		    FIRE_JBC_FATAL_RST_EN_APE_P_INT |
+		    FIRE_JBC_FATAL_RST_EN_PIO_CPE_INT |
+		    FIRE_JBC_FATAL_RST_EN_JTCEEW_P_INT |
+		    FIRE_JBC_FATAL_RST_EN_JTCEEI_P_INT |
+		    FIRE_JBC_FATAL_RST_EN_JTCEER_P_INT);
+		FIRE_CTRL_SET(sc, FIRE_JBC_CORE_BLOCK_INT_EN, ~0ULL);
+	}
+
+	/* TLU initialization */
+	FIRE_PCI_SET(sc, FO_PCI_TLU_OEVENT_STAT_CLR,
+	    FO_PCI_TLU_OEVENT_S_MASK | FO_PCI_TLU_OEVENT_P_MASK);
+	/* not enabled by OpenSolaris */
+	FIRE_PCI_SET(sc, FO_PCI_TLU_OEVENT_INT_EN,
+	    FO_PCI_TLU_OEVENT_S_MASK | FO_PCI_TLU_OEVENT_P_MASK);
+	FIRE_PCI_SET(sc, FO_PCI_TLU_UERR_STAT_CLR,
+	    FO_PCI_TLU_UERR_INT_S_MASK | FO_PCI_TLU_UERR_INT_P_MASK);
+	/* not enabled by OpenSolaris */
+	FIRE_PCI_SET(sc, FO_PCI_TLU_UERR_INT_EN,
+	    FO_PCI_TLU_UERR_INT_S_MASK | FO_PCI_TLU_UERR_INT_P_MASK);
+	FIRE_PCI_SET(sc, FO_PCI_TLU_CERR_STAT_CLR,
+	    FO_PCI_TLU_CERR_INT_S_MASK | FO_PCI_TLU_CERR_INT_P_MASK);
+	/* not enabled by OpenSolaris */
+	FIRE_PCI_SET(sc, FO_PCI_TLU_CERR_INT_EN,
+	    FO_PCI_TLU_CERR_INT_S_MASK | FO_PCI_TLU_CERR_INT_P_MASK);
+	val = FIRE_PCI_READ_8(sc, FO_PCI_TLU_CTRL) |
+	    ((FO_PCI_TLU_CTRL_L0S_TIM_DFLT << FO_PCI_TLU_CTRL_L0S_TIM_SHFT) &
+	    FO_PCI_TLU_CTRL_L0S_TIM_MASK) |
+	    ((FO_PCI_TLU_CTRL_CFG_DFLT << FO_PCI_TLU_CTRL_CFG_SHFT) &
+	    FO_PCI_TLU_CTRL_CFG_MASK);
+	if (sc->sc_mode == FIRE_MODE_OBERON)
+		val &= ~FO_PCI_TLU_CTRL_NWPR_EN;
+	val |= FO_PCI_TLU_CTRL_CFG_REMAIN_DETECT_QUIET;
+	FIRE_PCI_SET(sc, FO_PCI_TLU_CTRL, val);
+	FIRE_PCI_SET(sc, FO_PCI_TLU_DEV_CTRL, 0);
+	FIRE_PCI_SET(sc, FO_PCI_TLU_LNK_CTRL, FO_PCI_TLU_LNK_CTRL_CLK);
+
+	/* DLU/LPU initialization */
+	if (sc->sc_mode == FIRE_MODE_OBERON)
+		FIRE_PCI_SET(sc, FO_PCI_LPU_INT_MASK, 0);
+	else
+		FIRE_PCI_SET(sc, FO_PCI_LPU_RST, 0);
+	FIRE_PCI_SET(sc, FO_PCI_LPU_LNK_LYR_CFG,
+	    FO_PCI_LPU_LNK_LYR_CFG_VC0_EN);
+	FIRE_PCI_SET(sc, FO_PCI_LPU_FLW_CTRL_UPDT_CTRL,
+	    FO_PCI_LPU_FLW_CTRL_UPDT_CTRL_FC0_NP_EN |
+	    FO_PCI_LPU_FLW_CTRL_UPDT_CTRL_FC0_P_EN);
+	if (sc->sc_mode == FIRE_MODE_OBERON)
+		FIRE_PCI_SET(sc, FO_PCI_LPU_TXLNK_RPLY_TMR_THRS,
+		    (OBERON_PCI_LPU_TXLNK_RPLY_TMR_THRS_DFLT <<
+		    FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_SHFT) &
+		    FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_MASK);
+	else {
+		switch ((FIRE_PCI_READ_8(sc, FO_PCI_TLU_LNK_STAT) &
+		    FO_PCI_TLU_LNK_STAT_WDTH_MASK) >>
+		    FO_PCI_TLU_LNK_STAT_WDTH_SHFT) {
+		case 1:
+			lw = 0;
+			break;
+		case 4:
+			lw = 1;
+			break;
+		case 8:
+			lw = 2;
+			break;
+		case 16:
+			lw = 3;
+			break;
+		default:
+			lw = 0;
+		}
+		mps = (FIRE_PCI_READ_8(sc, FO_PCI_TLU_CTRL) &
+		    FO_PCI_TLU_CTRL_CFG_MPS_MASK) >>
+		    FO_PCI_TLU_CTRL_CFG_MPS_SHFT;
+		i = sizeof(fire_freq_nak_tmr_thrs) /
+		    sizeof(*fire_freq_nak_tmr_thrs);
+		if (mps >= i)
+			mps = i - 1;
+		FIRE_PCI_SET(sc, FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS,
+		    (fire_freq_nak_tmr_thrs[mps][lw] <<
+		    FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS_SHFT) &
+		    FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS_MASK);
+		FIRE_PCI_SET(sc, FO_PCI_LPU_TXLNK_RPLY_TMR_THRS,
+		    (fire_rply_tmr_thrs[mps][lw] <<
+		    FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_SHFT) &
+		    FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_MASK);
+		FIRE_PCI_SET(sc, FO_PCI_LPU_TXLNK_RTR_FIFO_PTR,
+		    ((FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_DFLT <<
+		    FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_SHFT) &
+		    FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_MASK) |
+		    ((FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_DFLT <<
+		    FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_SHFT) &
+		    FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_MASK));
+		FIRE_PCI_SET(sc, FO_PCI_LPU_LTSSM_CFG2,
+		    (FO_PCI_LPU_LTSSM_CFG2_12_TO_DFLT <<
+		    FO_PCI_LPU_LTSSM_CFG2_12_TO_SHFT) &
+		    FO_PCI_LPU_LTSSM_CFG2_12_TO_MASK);
+		FIRE_PCI_SET(sc, FO_PCI_LPU_LTSSM_CFG3,
+		    (FO_PCI_LPU_LTSSM_CFG3_2_TO_DFLT <<
+		    FO_PCI_LPU_LTSSM_CFG3_2_TO_SHFT) &
+		    FO_PCI_LPU_LTSSM_CFG3_2_TO_MASK);
+		FIRE_PCI_SET(sc, FO_PCI_LPU_LTSSM_CFG4,
+		    ((FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_DFLT <<
+		    FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_SHFT) &
+		    FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_MASK) |
+		    ((FO_PCI_LPU_LTSSM_CFG4_N_FTS_DFLT <<
+		    FO_PCI_LPU_LTSSM_CFG4_N_FTS_SHFT) &
+		    FO_PCI_LPU_LTSSM_CFG4_N_FTS_MASK));
+		FIRE_PCI_SET(sc, FO_PCI_LPU_LTSSM_CFG5, 0);
+	}
+
+	/* ILU initialization */
+	FIRE_PCI_SET(sc, FO_PCI_ILU_ERR_STAT_CLR, ~0ULL);
+	/* not enabled by OpenSolaris */
+	FIRE_PCI_SET(sc, FO_PCI_ILU_INT_EN, ~0ULL);
+
+	/* IMU initialization */
+	FIRE_PCI_SET(sc, FO_PCI_IMU_ERR_STAT_CLR, ~0ULL);
+	FIRE_PCI_SET(sc, FO_PCI_IMU_INT_EN,
+	    FIRE_PCI_READ_8(sc, FO_PCI_IMU_INT_EN) &
+	    ~(FO_PCI_IMU_ERR_INT_FATAL_MES_NOT_EN_S |
+	    FO_PCI_IMU_ERR_INT_NFATAL_MES_NOT_EN_S |
+	    FO_PCI_IMU_ERR_INT_COR_MES_NOT_EN_S |
+	    FO_PCI_IMU_ERR_INT_FATAL_MES_NOT_EN_P |
+	    FO_PCI_IMU_ERR_INT_NFATAL_MES_NOT_EN_P |
+	    FO_PCI_IMU_ERR_INT_COR_MES_NOT_EN_P));
+
+	/* MMU initialization */
+	FIRE_PCI_SET(sc, FO_PCI_MMU_ERR_STAT_CLR,
+	    FO_PCI_MMU_ERR_INT_S_MASK | FO_PCI_MMU_ERR_INT_P_MASK);
+	/* not enabled by OpenSolaris */
+	FIRE_PCI_SET(sc, FO_PCI_MMU_INT_EN,
+	    FO_PCI_MMU_ERR_INT_S_MASK | FO_PCI_MMU_ERR_INT_P_MASK);
+
+	/* DMC initialization */
+	FIRE_PCI_SET(sc, FO_PCI_DMC_CORE_BLOCK_INT_EN, ~0ULL);
+	FIRE_PCI_SET(sc, FO_PCI_DMC_DBG_SEL_PORTA, 0);
+	FIRE_PCI_SET(sc, FO_PCI_DMC_DBG_SEL_PORTB, 0);
+
+	/* PEC initialization */
+	FIRE_PCI_SET(sc, FO_PCI_PEC_CORE_BLOCK_INT_EN, ~0ULL);
+
+	/* Establish handlers for interesting interrupts. */
+	if ((ino_bitmap & (1ULL << FO_DMC_PEC_INO)) != 0)
+		fire_set_intr(sc, 1, FO_DMC_PEC_INO, fire_dmc_pec, sc);
+	if ((ino_bitmap & (1ULL << FO_XCB_INO)) != 0)
+		fire_set_intr(sc, 0, FO_XCB_INO, fire_xcb, sc);
+
+	/* MSI/MSI-X support */
+	if (OF_getprop(node, "#msi", &sc->sc_msi_count,
+	    sizeof(sc->sc_msi_count)) == -1)
+		panic("%s: could not determine MSI count", __func__);
+	if (OF_getprop(node, "msi-ranges", &msi_ranges,
+	    sizeof(msi_ranges)) == -1)
+		sc->sc_msi_first = 0;
+	else
+		sc->sc_msi_first = msi_ranges.first;
+	if (OF_getprop(node, "msi-data-mask", &sc->sc_msi_data_mask,
+	    sizeof(sc->sc_msi_data_mask)) == -1)
+		panic("%s: could not determine MSI data mask", __func__);
+	if (OF_getprop(node, "msix-data-width", &sc->sc_msix_data_width,
+	    sizeof(sc->sc_msix_data_width)) > 0)
+		sc->sc_flags |= FIRE_MSIX;
+	if (OF_getprop(node, "msi-address-ranges", &msi_addr_ranges,
+	    sizeof(msi_addr_ranges)) == -1)
+		panic("%s: could not determine MSI address ranges", __func__);
+	sc->sc_msi_addr32 = OFW_PCI_MSI_ADDR_RANGE_32(&msi_addr_ranges);
+	sc->sc_msi_addr64 = OFW_PCI_MSI_ADDR_RANGE_64(&msi_addr_ranges);
+	if (OF_getprop(node, "#msi-eqs", &sc->sc_msiq_count,
+	    sizeof(sc->sc_msiq_count)) == -1)
+		panic("%s: could not determine MSI event queue count",
+		    __func__);
+	if (OF_getprop(node, "msi-eq-size", &sc->sc_msiq_size,
+	    sizeof(sc->sc_msiq_size)) == -1)
+		panic("%s: could not determine MSI event queue size",
+		    __func__);
+	if (OF_getprop(node, "msi-eq-to-devino", &msi_eq_to_devino,
+	    sizeof(msi_eq_to_devino)) == -1 &&
+	    OF_getprop(node, "msi-eq-devino", &msi_eq_to_devino,
+	    sizeof(msi_eq_to_devino)) == -1) {
+		sc->sc_msiq_first = 0;
+		sc->sc_msiq_ino_first = FO_EQ_FIRST_INO;
+	} else {
+		sc->sc_msiq_first = msi_eq_to_devino.eq_first;
+		sc->sc_msiq_ino_first = msi_eq_to_devino.devino_first;
+	}
+	if (sc->sc_msiq_ino_first < FO_EQ_FIRST_INO ||
+	    sc->sc_msiq_ino_first + sc->sc_msiq_count - 1 > FO_EQ_LAST_INO)
+		panic("%s: event queues exceed INO range", __func__);
+	sc->sc_msi_bitmap = malloc(roundup2(sc->sc_msi_count, NBBY) / NBBY,
+	    M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (sc->sc_msi_bitmap == NULL)
+		panic("%s: could not malloc MSI bitmap", __func__);
+	sc->sc_msi_msiq_table = malloc(sc->sc_msi_count *
+	    sizeof(*sc->sc_msi_msiq_table), M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (sc->sc_msi_msiq_table == NULL)
+		panic("%s: could not malloc MSI-MSI event queue table",
+		    __func__);
+	sc->sc_msiq_bitmap = malloc(roundup2(sc->sc_msiq_count, NBBY) / NBBY,
+	    M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (sc->sc_msiq_bitmap == NULL)
+		panic("%s: could not malloc MSI event queue bitmap", __func__);
+	j = FO_EQ_RECORD_SIZE * FO_EQ_NRECORDS * sc->sc_msiq_count;
+	sc->sc_msiq = contigmalloc(j, M_DEVBUF, M_NOWAIT, 0, ~0UL,
+	    FO_EQ_ALIGNMENT, 0);
+	if (sc->sc_msiq == NULL)
+		panic("%s: could not contigmalloc MSI event queue", __func__);
+	memset(sc->sc_msiq, 0, j);
+	FIRE_PCI_SET(sc, FO_PCI_EQ_BASE_ADDR, FO_PCI_EQ_BASE_ADDR_BYPASS |
+	    (pmap_kextract((vm_offset_t)sc->sc_msiq) &
+	    FO_PCI_EQ_BASE_ADDR_MASK));
+	for (i = 0; i < sc->sc_msi_count; i++) {
+		j = (i + sc->sc_msi_first) << 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_MAP_BASE + j,
+		    FIRE_PCI_READ_8(sc, FO_PCI_MSI_MAP_BASE + j) &
+		    ~FO_PCI_MSI_MAP_V);
+	}
+	for (i = 0; i < sc->sc_msiq_count; i++) {
+		j = i + sc->sc_msiq_ino_first;
+		if ((ino_bitmap & (1ULL << j)) == 0) {
+			mtx_lock(&sc->sc_msi_mtx);
+			setbit(sc->sc_msiq_bitmap, i);
+			mtx_unlock(&sc->sc_msi_mtx);
+		}
+		fmqa = intr_vectors[INTMAP_VEC(sc->sc_ign, j)].iv_icarg;
+		mtx_init(&fmqa->fmqa_mtx, "msiq_mtx", NULL, MTX_SPIN);
+		fmqa->fmqa_base =
+		    (struct fo_msiq_record *)((caddr_t)sc->sc_msiq +
+		    (FO_EQ_RECORD_SIZE * FO_EQ_NRECORDS * i));
+		j = i + sc->sc_msiq_first;
+		fmqa->fmqa_msiq = j;
+		j <<= 3;
+		fmqa->fmqa_head = FO_PCI_EQ_HD_BASE + j;
+		fmqa->fmqa_tail = FO_PCI_EQ_TL_BASE + j;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + j,
+		    FO_PCI_EQ_CTRL_CLR_COVERR | FO_PCI_EQ_CTRL_CLR_E2I |
+		    FO_PCI_EQ_CTRL_CLR_DIS);
+		FIRE_PCI_WRITE_8(sc, fmqa->fmqa_tail,
+		    (0 << FO_PCI_EQ_TL_SHFT) & FO_PCI_EQ_TL_MASK);
+		FIRE_PCI_WRITE_8(sc, fmqa->fmqa_head,
+		    (0 << FO_PCI_EQ_HD_SHFT) & FO_PCI_EQ_HD_MASK);
+	}
+	FIRE_PCI_SET(sc, FO_PCI_MSI_32_BIT_ADDR, sc->sc_msi_addr32 &
+	    FO_PCI_MSI_32_BIT_ADDR_MASK);
+	FIRE_PCI_SET(sc, FO_PCI_MSI_64_BIT_ADDR, sc->sc_msi_addr64 &
+	    FO_PCI_MSI_64_BIT_ADDR_MASK);
+
+	/*
+	 * Establish a handler for interesting PCIe messages and disable
+	 * unintersting ones.
+	 */
+	mtx_lock(&sc->sc_msi_mtx);
+	for (i = 0; i < sc->sc_msiq_count; i++) {
+		if (isclr(sc->sc_msiq_bitmap, i) != 0) {
+			j = i;
+			break;
+		}
+	}
+	if (i == sc->sc_msiq_count) {
+		mtx_unlock(&sc->sc_msi_mtx);
+		panic("%s: no spare event queue for PCIe messages", __func__);
+	}
+	setbit(sc->sc_msiq_bitmap, j);
+	mtx_unlock(&sc->sc_msi_mtx);
+	i = INTMAP_VEC(sc->sc_ign, j + sc->sc_msiq_ino_first);
+	if (bus_set_resource(dev, SYS_RES_IRQ, 2, i, 1) != 0)
+		panic("%s: failed to add interrupt for PCIe messages",
+		    __func__);
+	fire_set_intr(sc, 2, INTINO(i), fire_pcie, intr_vectors[i].iv_icarg);
+	j += sc->sc_msiq_first;
+	/*
+	 * "Please note that setting the EQNUM field to a value larger than
+	 * 35 will yield unpredictable results."
+	 */
+	if (j > 35)
+		panic("%s: invalid queue for PCIe messages (%d)",
+		    __func__, j);
+	FIRE_PCI_SET(sc, FO_PCI_ERR_COR, FO_PCI_ERR_PME_V |
+	    ((j << FO_PCI_ERR_PME_EQNUM_SHFT) & FO_PCI_ERR_PME_EQNUM_MASK));
+	FIRE_PCI_SET(sc, FO_PCI_ERR_NONFATAL, FO_PCI_ERR_PME_V |
+	    ((j << FO_PCI_ERR_PME_EQNUM_SHFT) & FO_PCI_ERR_PME_EQNUM_MASK));
+	FIRE_PCI_SET(sc, FO_PCI_ERR_FATAL, FO_PCI_ERR_PME_V |
+	    ((j << FO_PCI_ERR_PME_EQNUM_SHFT) & FO_PCI_ERR_PME_EQNUM_MASK));
+	FIRE_PCI_SET(sc, FO_PCI_PM_PME, 0);
+	FIRE_PCI_SET(sc, FO_PCI_PME_TO_ACK, 0);
+	FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_SET_BASE + (j << 3),
+	    FO_PCI_EQ_CTRL_SET_EN);
+
+#define	TC_COUNTER_MAX_MASK	0xffffffff
+
+	/*
+	 * Setup JBC/UBC performance counter 0 in bus cycle counting
+	 * mode as timecounter.
+	 */
+	if (device_get_unit(dev) == 0) {
+		FIRE_CTRL_SET(sc, FO_XBC_PRF_CNT0, 0);
+		FIRE_CTRL_SET(sc, FO_XBC_PRF_CNT1, 0);
+		FIRE_CTRL_SET(sc, FO_XBC_PRF_CNT_SEL,
+		    (FO_XBC_PRF_CNT_NONE << FO_XBC_PRF_CNT_CNT1_SHFT) |
+		    (FO_XBC_PRF_CNT_XB_CLK << FO_XBC_PRF_CNT_CNT0_SHFT));
+		tc = malloc(sizeof(*tc), M_DEVBUF, M_NOWAIT | M_ZERO);
+		if (tc == NULL)
+			panic("%s: could not malloc timecounter", __func__);
+		tc->tc_get_timecount = fire_get_timecount;
+		tc->tc_counter_mask = TC_COUNTER_MAX_MASK;
+		if (OF_getprop(OF_peer(0), "clock-frequency", &prop,
+		    sizeof(prop)) == -1)
+			panic("%s: could not determine clock frequency",
+			    __func__);
+		tc->tc_frequency = prop;
+		tc->tc_name = strdup(device_get_nameunit(dev), M_DEVBUF);
+		tc->tc_priv = sc;
+		/*
+		 * Due to initial problems with the JBus-driven performance
+		 * counters not advancing which might be firmware dependent
+		 * ensure that it actually works.
+		 */
+		if (fire_get_timecount(tc) - fire_get_timecount(tc) != 0)
+			tc->tc_quality = FIRE_PERF_CNT_QLTY;
+		else
+			tc->tc_quality = -FIRE_PERF_CNT_QLTY;
+		tc_init(tc);
+	}
+
+	/*
+	 * Set up the IOMMU.  Both Fire and Oberon have one per PBM, but
+	 * neither has a streaming buffer.
+	 */
+	memcpy(&sc->sc_dma_methods, &iommu_dma_methods,
+	    sizeof(sc->sc_dma_methods));
+	sc->sc_is.is_flags = IOMMU_FIRE | IOMMU_PRESERVE_PROM;
+	if (sc->sc_mode == FIRE_MODE_OBERON) {
+		sc->sc_is.is_flags |= IOMMU_FLUSH_CACHE;
+		sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(OBERON_IOMMU_BITS);
+	} else {
+		sc->sc_dma_methods.dm_dmamap_sync = fire_dmamap_sync;
+		sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(FIRE_IOMMU_BITS);
+	}
+	sc->sc_is.is_sb[0] = sc->sc_is.is_sb[1] = 0;
+	/* Punch in our copies. */
+	sc->sc_is.is_bustag = rman_get_bustag(sc->sc_mem_res[FIRE_PCI]);
+	sc->sc_is.is_bushandle = rman_get_bushandle(sc->sc_mem_res[FIRE_PCI]);
+	sc->sc_is.is_iommu = FO_PCI_MMU;
+	val = FIRE_PCI_READ_8(sc, FO_PCI_MMU + IMR_CTL);
+	iommu_init(device_get_nameunit(dev), &sc->sc_is, 7, -1, 0);
+#ifdef FIRE_DEBUG
+	device_printf(dev, "FO_PCI_MMU + IMR_CTL 0x%016llx -> 0x%016llx\n",
+	    (long long unsigned)val, (long long unsigned)sc->sc_is.is_cr);
+#endif
+	/* Create our DMA tag. */
+	if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0x100000000,
+	    sc->sc_is.is_pmaxaddr, ~0, NULL, NULL, sc->sc_is.is_pmaxaddr,
+	    0xff, 0xffffffff, 0, NULL, NULL, &dmat) != 0)
+		panic("%s: could not create PCI DMA tag", __func__);
+	dmat->dt_cookie = &sc->sc_is;
+	dmat->dt_mt = &sc->sc_dma_methods;
+
+	if (ofw_pci_attach_common(dev, dmat, FO_IO_SIZE, FO_MEM_SIZE) != 0)
+		panic("%s: ofw_pci_attach_common() failed", __func__);
+
+#define	FIRE_SYSCTL_ADD_UINT(name, arg, desc)				\
+	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),			\
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,	\
+	    (name), CTLFLAG_RD, (arg), 0, (desc))
+
+	FIRE_SYSCTL_ADD_UINT("ilu_err", &sc->sc_stats_ilu_err,
+	    "ILU unknown errors");
+	FIRE_SYSCTL_ADD_UINT("jbc_ce_async", &sc->sc_stats_jbc_ce_async,
+	    "JBC correctable errors");
+	FIRE_SYSCTL_ADD_UINT("jbc_unsol_int", &sc->sc_stats_jbc_unsol_int,
+	    "JBC unsolicited interrupt ACK/NACK errors");
+	FIRE_SYSCTL_ADD_UINT("jbc_unsol_rd", &sc->sc_stats_jbc_unsol_rd,
+	    "JBC unsolicited read response errors");
+	FIRE_SYSCTL_ADD_UINT("mmu_err", &sc->sc_stats_mmu_err, "MMU errors");
+	FIRE_SYSCTL_ADD_UINT("tlu_ce", &sc->sc_stats_tlu_ce,
+	    "DLU/TLU correctable errors");
+	FIRE_SYSCTL_ADD_UINT("tlu_oe_non_fatal",
+	    &sc->sc_stats_tlu_oe_non_fatal,
+	    "DLU/TLU other event non-fatal errors summary");
+	FIRE_SYSCTL_ADD_UINT("tlu_oe_rx_err", &sc->sc_stats_tlu_oe_rx_err,
+	    "DLU/TLU receive other event errors");
+	FIRE_SYSCTL_ADD_UINT("tlu_oe_tx_err", &sc->sc_stats_tlu_oe_tx_err,
+	    "DLU/TLU transmit other event errors");
+	FIRE_SYSCTL_ADD_UINT("ubc_dmardue", &sc->sc_stats_ubc_dmardue,
+	    "UBC DMARDUE erros");
+
+#undef FIRE_SYSCTL_ADD_UINT
+
+	device_add_child(dev, "pci", -1);
+	return (bus_generic_attach(dev));
+}
+
+static void
+fire_set_intr(struct fire_softc *sc, u_int index, u_int ino,
+    driver_filter_t handler, void *arg)
+{
+	u_long vec;
+	int rid;
+
+	rid = index;
+	sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev,
+	    SYS_RES_IRQ, &rid, RF_ACTIVE);
+	if (sc->sc_irq_res[index] == NULL ||
+	    INTINO(vec = rman_get_start(sc->sc_irq_res[index])) != ino ||
+	    INTIGN(vec) != sc->sc_ign ||
+	    intr_vectors[vec].iv_ic != &fire_ic ||
+	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index],
+	    INTR_TYPE_MISC | INTR_BRIDGE, handler, NULL, arg,
+	    &sc->sc_ihand[index]) != 0)
+		panic("%s: failed to set up interrupt %d", __func__, index);
+}
+
+static int
+fire_intr_register(struct fire_softc *sc, u_int ino)
+{
+	struct fire_icarg *fica;
+	bus_addr_t intrclr, intrmap;
+	int error;
+
+	if (fire_get_intrmap(sc, ino, &intrmap, &intrclr) == 0)
+		return (ENXIO);
+	fica = malloc((ino >= FO_EQ_FIRST_INO && ino <= FO_EQ_LAST_INO) ?
+	    sizeof(struct fire_msiqarg) : sizeof(struct fire_icarg), M_DEVBUF,
+	    M_NOWAIT | M_ZERO);
+	if (fica == NULL)
+		return (ENOMEM);
+	fica->fica_sc = sc;
+	fica->fica_map = intrmap;
+	fica->fica_clr = intrclr;
+	error = (intr_controller_register(INTMAP_VEC(sc->sc_ign, ino),
+	    &fire_ic, fica));
+	if (error != 0)
+		free(fica, M_DEVBUF);
+	return (error);
+}
+
+static int
+fire_get_intrmap(struct fire_softc *sc, u_int ino, bus_addr_t *intrmapptr,
+    bus_addr_t *intrclrptr)
+{
+
+	if (ino > FO_MAX_INO) {
+		device_printf(sc->sc_dev, "out of range INO %d requested\n",
+		    ino);
+		return (0);
+	}
+
+	ino <<= 3;
+	if (intrmapptr != NULL)
+		*intrmapptr = FO_PCI_INT_MAP_BASE + ino;
+	if (intrclrptr != NULL)
+		*intrclrptr = FO_PCI_INT_CLR_BASE + ino;
+	return (1);
+}
+
+/*
+ * Interrupt handlers
+ */
+static int
+fire_dmc_pec(void *arg)
+{
+	struct fire_softc *sc;
+	device_t dev;
+	uint64_t cestat, dmcstat, ilustat, imustat, mcstat, mmustat, mmutfar;
+	uint64_t mmutfsr, oestat, pecstat, uestat, val;
+	u_int fatal, oenfatal;
+
+	fatal = 0;
+	sc = arg;
+	dev = sc->sc_dev;
+	mtx_lock_spin(&sc->sc_pcib_mtx);
+	mcstat = FIRE_PCI_READ_8(sc, FO_PCI_MULTI_CORE_ERR_STAT);
+	if ((mcstat & FO_PCI_MULTI_CORE_ERR_STAT_DMC) != 0) {
+		dmcstat = FIRE_PCI_READ_8(sc, FO_PCI_DMC_CORE_BLOCK_ERR_STAT);
+		if ((dmcstat & FO_PCI_DMC_CORE_BLOCK_INT_EN_IMU) != 0) {
+			imustat = FIRE_PCI_READ_8(sc, FO_PCI_IMU_INT_STAT);
+			device_printf(dev, "IMU error %#llx\n",
+			    (unsigned long long)imustat);
+			if ((imustat &
+			    FO_PCI_IMU_ERR_INT_EQ_NOT_EN_P) != 0) {
+				fatal = 1;
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_IMU_SCS_ERR_LOG);
+				device_printf(dev, "SCS error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((imustat & FO_PCI_IMU_ERR_INT_EQ_OVER_P) != 0) {
+				fatal = 1;
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_IMU_EQS_ERR_LOG);
+				device_printf(dev, "EQS error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((imustat & (FO_PCI_IMU_ERR_INT_MSI_MAL_ERR_P |
+			    FO_PCI_IMU_ERR_INT_MSI_PAR_ERR_P |
+			    FO_PCI_IMU_ERR_INT_PMEACK_MES_NOT_EN_P |
+			    FO_PCI_IMU_ERR_INT_PMPME_MES_NOT_EN_P |
+			    FO_PCI_IMU_ERR_INT_FATAL_MES_NOT_EN_P |
+			    FO_PCI_IMU_ERR_INT_NFATAL_MES_NOT_EN_P |
+			    FO_PCI_IMU_ERR_INT_COR_MES_NOT_EN_P |
+			    FO_PCI_IMU_ERR_INT_MSI_NOT_EN_P)) != 0) {
+				fatal = 1;
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_IMU_RDS_ERR_LOG);
+				device_printf(dev, "RDS error log %#llx\n",
+				    (unsigned long long)val);
+			}
+		}
+		if ((dmcstat & FO_PCI_DMC_CORE_BLOCK_INT_EN_MMU) != 0) {
+			fatal = 1;
+			mmustat = FIRE_PCI_READ_8(sc, FO_PCI_MMU_INT_STAT);
+			mmutfar = FIRE_PCI_READ_8(sc,
+			    FO_PCI_MMU_TRANS_FAULT_ADDR);
+			mmutfsr = FIRE_PCI_READ_8(sc,
+			    FO_PCI_MMU_TRANS_FAULT_STAT);
+			if ((mmustat & (FO_PCI_MMU_ERR_INT_TBW_DPE_P |
+			    FO_PCI_MMU_ERR_INT_TBW_ERR_P |
+			    FO_PCI_MMU_ERR_INT_TBW_UDE_P |
+			    FO_PCI_MMU_ERR_INT_TBW_DME_P |
+			    FO_PCI_MMU_ERR_INT_TTC_CAE_P |
+			    FIRE_PCI_MMU_ERR_INT_TTC_DPE_P |
+			    OBERON_PCI_MMU_ERR_INT_TTC_DUE_P |
+			    FO_PCI_MMU_ERR_INT_TRN_ERR_P)) != 0)
+				fatal = 1;
+			else {
+				sc->sc_stats_mmu_err++;
+				FIRE_PCI_WRITE_8(sc, FO_PCI_MMU_ERR_STAT_CLR,
+				    mmustat);
+			}
+			device_printf(dev,
+			    "MMU error %#llx: TFAR %#llx TFSR %#llx\n",
+			    (unsigned long long)mmustat,
+			    (unsigned long long)mmutfar,
+			    (unsigned long long)mmutfsr);
+		}
+	}
+	if ((mcstat & FO_PCI_MULTI_CORE_ERR_STAT_PEC) != 0) {
+		pecstat = FIRE_PCI_READ_8(sc, FO_PCI_PEC_CORE_BLOCK_INT_STAT);
+		if ((pecstat & FO_PCI_PEC_CORE_BLOCK_INT_STAT_UERR) != 0) {
+			fatal = 1;
+			uestat = FIRE_PCI_READ_8(sc,
+			    FO_PCI_TLU_UERR_INT_STAT);
+			device_printf(dev,
+			    "DLU/TLU uncorrectable error %#llx\n",
+			    (unsigned long long)uestat);
+			if ((uestat & (FO_PCI_TLU_UERR_INT_UR_P |
+			    OBERON_PCI_TLU_UERR_INT_POIS_P |
+			    FO_PCI_TLU_UERR_INT_MFP_P |
+			    FO_PCI_TLU_UERR_INT_ROF_P |
+			    FO_PCI_TLU_UERR_INT_UC_P |
+			    FIRE_PCI_TLU_UERR_INT_PP_P |
+			    OBERON_PCI_TLU_UERR_INT_POIS_P)) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_RX_UERR_HDR1_LOG);
+				device_printf(dev,
+				    "receive header log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_RX_UERR_HDR2_LOG);
+				device_printf(dev,
+				    "receive header log 2 %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((uestat & FO_PCI_TLU_UERR_INT_CTO_P) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_TX_UERR_HDR1_LOG);
+				device_printf(dev,
+				    "transmit header log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_TX_UERR_HDR2_LOG);
+				device_printf(dev,
+				    "transmit header log 2 %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((uestat & FO_PCI_TLU_UERR_INT_DLP_P) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_LPU_LNK_LYR_INT_STAT);
+				device_printf(dev,
+				    "link layer interrupt and status %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((uestat & FO_PCI_TLU_UERR_INT_TE_P) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_LPU_PHY_LYR_INT_STAT);
+				device_printf(dev,
+				    "phy layer interrupt and status %#llx\n",
+				    (unsigned long long)val);
+			}
+		}
+		if ((pecstat & FO_PCI_PEC_CORE_BLOCK_INT_STAT_CERR) != 0) {
+			sc->sc_stats_tlu_ce++;
+			cestat = FIRE_PCI_READ_8(sc,
+			    FO_PCI_TLU_CERR_INT_STAT);
+			device_printf(dev,
+			    "DLU/TLU correctable error %#llx\n",
+			    (unsigned long long)cestat);
+			val = FIRE_PCI_READ_8(sc,
+			    FO_PCI_LPU_LNK_LYR_INT_STAT);
+			device_printf(dev,
+			    "link layer interrupt and status %#llx\n",
+			    (unsigned long long)val);
+			if ((cestat & FO_PCI_TLU_CERR_INT_RE_P) != 0) {
+				FIRE_PCI_WRITE_8(sc,
+				    FO_PCI_LPU_LNK_LYR_INT_STAT, val);
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_LPU_PHY_LYR_INT_STAT);
+				device_printf(dev,
+				    "phy layer interrupt and status %#llx\n",
+				    (unsigned long long)val);
+			}
+			FIRE_PCI_WRITE_8(sc, FO_PCI_TLU_CERR_STAT_CLR,
+			    cestat);
+		}
+		if ((pecstat & FO_PCI_PEC_CORE_BLOCK_INT_STAT_OEVENT) != 0) {
+			oenfatal = 0;
+			oestat = FIRE_PCI_READ_8(sc,
+			    FO_PCI_TLU_OEVENT_INT_STAT);
+			device_printf(dev, "DLU/TLU other event %#llx\n",
+			    (unsigned long long)oestat);
+			if ((oestat & (FO_PCI_TLU_OEVENT_MFC_P |
+			    FO_PCI_TLU_OEVENT_MRC_P |
+			    FO_PCI_TLU_OEVENT_WUC_P |
+			    FO_PCI_TLU_OEVENT_RUC_P |
+			    FO_PCI_TLU_OEVENT_CRS_P)) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_RX_OEVENT_HDR1_LOG);
+				device_printf(dev,
+				    "receive header log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_RX_OEVENT_HDR2_LOG);
+				device_printf(dev,
+				    "receive header log 2 %#llx\n",
+				    (unsigned long long)val);
+				if ((oestat & (FO_PCI_TLU_OEVENT_MFC_P |
+				    FO_PCI_TLU_OEVENT_MRC_P |
+				    FO_PCI_TLU_OEVENT_WUC_P |
+				    FO_PCI_TLU_OEVENT_RUC_P)) != 0)
+					fatal = 1;
+				else {
+					sc->sc_stats_tlu_oe_rx_err++;
+					oenfatal = 1;
+				}
+			}
+			if ((oestat & (FO_PCI_TLU_OEVENT_MFC_P |
+			    FO_PCI_TLU_OEVENT_CTO_P |
+			    FO_PCI_TLU_OEVENT_WUC_P |
+			    FO_PCI_TLU_OEVENT_RUC_P)) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_TX_OEVENT_HDR1_LOG);
+				device_printf(dev,
+				    "transmit header log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_TX_OEVENT_HDR2_LOG);
+				device_printf(dev,
+				    "transmit header log 2 %#llx\n",
+				    (unsigned long long)val);
+				if ((oestat & (FO_PCI_TLU_OEVENT_MFC_P |
+				    FO_PCI_TLU_OEVENT_CTO_P |
+				    FO_PCI_TLU_OEVENT_WUC_P |
+				    FO_PCI_TLU_OEVENT_RUC_P)) != 0)
+					fatal = 1;
+				else {
+					sc->sc_stats_tlu_oe_tx_err++;
+					oenfatal = 1;
+				}
+			}
+			if ((oestat & (FO_PCI_TLU_OEVENT_ERO_P |
+			    FO_PCI_TLU_OEVENT_EMP_P |
+			    FO_PCI_TLU_OEVENT_EPE_P |
+			    FIRE_PCI_TLU_OEVENT_ERP_P |
+			    OBERON_PCI_TLU_OEVENT_ERBU_P |
+			    FIRE_PCI_TLU_OEVENT_EIP_P |
+			    OBERON_PCI_TLU_OEVENT_EIUE_P)) != 0) {
+				fatal = 1;
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_LPU_LNK_LYR_INT_STAT);
+				device_printf(dev,
+				    "link layer interrupt and status %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((oestat & (FO_PCI_TLU_OEVENT_IIP_P |
+			    FO_PCI_TLU_OEVENT_EDP_P |
+			    FIRE_PCI_TLU_OEVENT_EHP_P |
+			    OBERON_PCI_TLU_OEVENT_TLUEITMO_S |
+			    FO_PCI_TLU_OEVENT_ERU_P)) != 0)
+				fatal = 1;
+			if ((oestat & (FO_PCI_TLU_OEVENT_NFP_P |
+			    FO_PCI_TLU_OEVENT_LWC_P |
+			    FO_PCI_TLU_OEVENT_LIN_P |
+			    FO_PCI_TLU_OEVENT_LRS_P |
+			    FO_PCI_TLU_OEVENT_LDN_P |
+			    FO_PCI_TLU_OEVENT_LUP_P)) != 0)
+				oenfatal = 1;
+			if (oenfatal != 0) {
+				sc->sc_stats_tlu_oe_non_fatal++;
+				FIRE_PCI_WRITE_8(sc,
+				    FO_PCI_TLU_OEVENT_STAT_CLR, oestat);
+				if ((oestat & FO_PCI_TLU_OEVENT_LIN_P) != 0)
+					FIRE_PCI_WRITE_8(sc,
+					    FO_PCI_LPU_LNK_LYR_INT_STAT,
+					    FIRE_PCI_READ_8(sc,
+					    FO_PCI_LPU_LNK_LYR_INT_STAT));
+			}
+		}
+		if ((pecstat & FO_PCI_PEC_CORE_BLOCK_INT_STAT_ILU) != 0) {
+			ilustat = FIRE_PCI_READ_8(sc, FO_PCI_ILU_INT_STAT);
+			device_printf(dev, "ILU error %#llx\n",
+			    (unsigned long long)ilustat);
+			if ((ilustat & (FIRE_PCI_ILU_ERR_INT_IHB_PE_P |
+			    FIRE_PCI_ILU_ERR_INT_IHB_PE_P)) != 0)
+			    fatal = 1;
+			else {
+				sc->sc_stats_ilu_err++;
+				FIRE_PCI_WRITE_8(sc, FO_PCI_ILU_INT_STAT,
+				    ilustat);
+			}
+		}
+	}
+	mtx_unlock_spin(&sc->sc_pcib_mtx);
+	if (fatal != 0)
+		panic("%s: fatal DMC/PEC error",
+		    device_get_nameunit(sc->sc_dev));
+	return (FILTER_HANDLED);
+}
+
+static int
+fire_xcb(void *arg)
+{
+	struct fire_softc *sc;
+	device_t dev;
+	uint64_t errstat, intstat, val;
+	u_int fatal;
+
+	fatal = 0;
+	sc = arg;
+	dev = sc->sc_dev;
+	mtx_lock_spin(&sc->sc_pcib_mtx);
+	if (sc->sc_mode == FIRE_MODE_OBERON) {
+		intstat = FIRE_CTRL_READ_8(sc, FO_XBC_INT_STAT);
+		device_printf(dev, "UBC error: interrupt status %#llx\n",
+		    (unsigned long long)intstat);
+		if ((intstat & ~(OBERON_UBC_ERR_INT_DMARDUEB_P |
+		    OBERON_UBC_ERR_INT_DMARDUEA_P)) != 0)
+			fatal = 1;
+		else
+			sc->sc_stats_ubc_dmardue++;
+		if (fatal != 0) {
+			mtx_unlock_spin(&sc->sc_pcib_mtx);
+			panic("%s: fatal UBC core block error",
+			    device_get_nameunit(sc->sc_dev));
+		} else {
+			FIRE_CTRL_SET(sc, FO_XBC_ERR_STAT_CLR, ~0ULL);
+			mtx_unlock_spin(&sc->sc_pcib_mtx);
+		}
+	} else {
+		errstat = FIRE_CTRL_READ_8(sc, FIRE_JBC_CORE_BLOCK_ERR_STAT);
+		if ((errstat & (FIRE_JBC_CORE_BLOCK_ERR_STAT_MERGE |
+		    FIRE_JBC_CORE_BLOCK_ERR_STAT_JBCINT |
+		    FIRE_JBC_CORE_BLOCK_ERR_STAT_DMCINT)) != 0) {
+			intstat = FIRE_CTRL_READ_8(sc, FO_XBC_INT_STAT);
+			device_printf(dev, "JBC interrupt status %#llx\n",
+			    (unsigned long long)intstat);
+			if ((intstat & FIRE_JBC_ERR_INT_EBUS_TO_P) != 0) {
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBC_CSR_ERR_LOG);
+				device_printf(dev, "CSR error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((intstat & (FIRE_JBC_ERR_INT_UNSOL_RD_P |
+			    FIRE_JBC_ERR_INT_UNSOL_INT_P)) != 0) {
+				if ((intstat &
+				    FIRE_JBC_ERR_INT_UNSOL_RD_P) != 0)
+					sc->sc_stats_jbc_unsol_rd++;
+				if ((intstat &
+				    FIRE_JBC_ERR_INT_UNSOL_INT_P) != 0)
+					sc->sc_stats_jbc_unsol_int++;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_DMCINT_IDC_ERR_LOG);
+				device_printf(dev,
+				    "DMCINT IDC error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((intstat & (FIRE_JBC_ERR_INT_MB_PER_P |
+			    FIRE_JBC_ERR_INT_MB_PEW_P)) != 0) {
+				fatal = 1;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_MERGE_TRANS_ERR_LOG);
+				device_printf(dev,
+				    "merge transaction error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((intstat & FIRE_JBC_ERR_INT_IJP_P) != 0) {
+				fatal = 1;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBCINT_OTRANS_ERR_LOG);
+				device_printf(dev,
+				    "JBCINT out transaction error log "
+				    "%#llx\n", (unsigned long long)val);
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBCINT_OTRANS_ERR_LOG2);
+				device_printf(dev,
+				    "JBCINT out transaction error log 2 "
+				    "%#llx\n", (unsigned long long)val);
+			}
+			if ((intstat & (FIRE_JBC_ERR_INT_UE_ASYN_P |
+			    FIRE_JBC_ERR_INT_CE_ASYN_P |
+			    FIRE_JBC_ERR_INT_JTE_P | FIRE_JBC_ERR_INT_JBE_P |
+			    FIRE_JBC_ERR_INT_JUE_P |
+			    FIRE_JBC_ERR_INT_ICISE_P |
+			    FIRE_JBC_ERR_INT_WR_DPE_P |
+			    FIRE_JBC_ERR_INT_RD_DPE_P |
+			    FIRE_JBC_ERR_INT_ILL_BMW_P |
+			    FIRE_JBC_ERR_INT_ILL_BMR_P |
+			    FIRE_JBC_ERR_INT_BJC_P)) != 0) {
+				if ((intstat & (FIRE_JBC_ERR_INT_UE_ASYN_P |
+				    FIRE_JBC_ERR_INT_JTE_P |
+				    FIRE_JBC_ERR_INT_JBE_P |
+				    FIRE_JBC_ERR_INT_JUE_P |
+				    FIRE_JBC_ERR_INT_ICISE_P |
+				    FIRE_JBC_ERR_INT_WR_DPE_P |
+				    FIRE_JBC_ERR_INT_RD_DPE_P |
+				    FIRE_JBC_ERR_INT_ILL_BMW_P |
+				    FIRE_JBC_ERR_INT_ILL_BMR_P |
+				    FIRE_JBC_ERR_INT_BJC_P)) != 0)
+					fatal = 1;
+				else
+					sc->sc_stats_jbc_ce_async++;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBCINT_ITRANS_ERR_LOG);
+				device_printf(dev,
+				    "JBCINT in transaction error log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBCINT_ITRANS_ERR_LOG2);
+				device_printf(dev,
+				    "JBCINT in transaction error log 2 "
+				    "%#llx\n", (unsigned long long)val);
+			}
+			if ((intstat & (FIRE_JBC_ERR_INT_PIO_UNMAP_RD_P |
+			    FIRE_JBC_ERR_INT_ILL_ACC_RD_P |
+			    FIRE_JBC_ERR_INT_PIO_UNMAP_P |
+			    FIRE_JBC_ERR_INT_PIO_DPE_P |
+			    FIRE_JBC_ERR_INT_PIO_CPE_P |
+			    FIRE_JBC_ERR_INT_ILL_ACC_P)) != 0) {
+				fatal = 1;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBC_CSR_ERR_LOG);
+				device_printf(dev,
+				    "DMCINT ODCD error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((intstat & (FIRE_JBC_ERR_INT_MB_PEA_P |
+			    FIRE_JBC_ERR_INT_CPE_P | FIRE_JBC_ERR_INT_APE_P |
+			    FIRE_JBC_ERR_INT_PIO_CPE_P |
+			    FIRE_JBC_ERR_INT_JTCEEW_P |
+			    FIRE_JBC_ERR_INT_JTCEEI_P |
+			    FIRE_JBC_ERR_INT_JTCEER_P)) != 0) {
+				fatal = 1;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_FATAL_ERR_LOG);
+				device_printf(dev, "fatal error log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_FATAL_ERR_LOG2);
+				device_printf(dev, "fatal error log 2 "
+				    "%#llx\n", (unsigned long long)val);
+			}
+			if (fatal != 0) {
+				mtx_unlock_spin(&sc->sc_pcib_mtx);
+				panic("%s: fatal JBC core block error",
+				    device_get_nameunit(sc->sc_dev));
+			} else {
+				FIRE_CTRL_SET(sc, FO_XBC_ERR_STAT_CLR, ~0ULL);
+				mtx_unlock_spin(&sc->sc_pcib_mtx);
+			}
+		} else {
+			mtx_unlock_spin(&sc->sc_pcib_mtx);
+			panic("%s: unknown JCB core block error status %#llx",
+			    device_get_nameunit(sc->sc_dev),
+			    (unsigned long long)errstat);
+		}
+	}
+	return (FILTER_HANDLED);
+}
+
+static int
+fire_pcie(void *arg)
+{
+	struct fire_msiqarg *fmqa;
+	struct fire_softc *sc;
+	struct fo_msiq_record *qrec;
+	device_t dev;
+	uint64_t word0;
+	u_int head, msg, msiq;
+
+	fmqa = arg;
+	sc = fmqa->fmqa_fica.fica_sc;
+	dev = sc->sc_dev;
+	msiq = fmqa->fmqa_msiq;
+	mtx_lock_spin(&fmqa->fmqa_mtx);
+	head = (FIRE_PCI_READ_8(sc, fmqa->fmqa_head) & FO_PCI_EQ_HD_MASK) >>
+	    FO_PCI_EQ_HD_SHFT;
+	qrec = &fmqa->fmqa_base[head];
+	word0 = qrec->fomqr_word0;
+	for (;;) {
+		KASSERT((word0 & FO_MQR_WORD0_FMT_TYPE_MSG) != 0,
+		    ("%s: received non-PCIe message in event queue %d "
+		    "(word0 %#llx)", device_get_nameunit(dev), msiq,
+		    (unsigned long long)word0));
+		msg = (word0 & FO_MQR_WORD0_DATA0_MASK) >>
+		    FO_MQR_WORD0_DATA0_SHFT;
+
+#define	PCIE_MSG_CODE_ERR_COR		0x30
+#define	PCIE_MSG_CODE_ERR_NONFATAL	0x31
+#define	PCIE_MSG_CODE_ERR_FATAL		0x33
+
+		if (msg == PCIE_MSG_CODE_ERR_COR)
+			device_printf(dev, "correctable PCIe error\n");
+		else if (msg == PCIE_MSG_CODE_ERR_NONFATAL ||
+		    msg == PCIE_MSG_CODE_ERR_FATAL)
+			panic("%s: %sfatal PCIe error",
+			    device_get_nameunit(dev),
+			    msg == PCIE_MSG_CODE_ERR_NONFATAL ? "non-" : "");
+		else
+			panic("%s: received unknown PCIe message %#x",
+			    device_get_nameunit(dev), msg);
+		qrec->fomqr_word0 &= ~FO_MQR_WORD0_FMT_TYPE_MASK;
+		head = (head + 1) % sc->sc_msiq_size;
+		qrec = &fmqa->fmqa_base[head];
+		word0 = qrec->fomqr_word0;
+		if (__predict_true((word0 & FO_MQR_WORD0_FMT_TYPE_MASK) == 0))
+			break;
+	}
+	FIRE_PCI_WRITE_8(sc, fmqa->fmqa_head, (head & FO_PCI_EQ_HD_MASK) <<
+	    FO_PCI_EQ_HD_SHFT);
+	if ((FIRE_PCI_READ_8(sc, fmqa->fmqa_tail) &
+	    FO_PCI_EQ_TL_OVERR) != 0) {
+		device_printf(dev, "event queue %d overflow\n", msiq);
+		msiq <<= 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + msiq,
+		    FIRE_PCI_READ_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + msiq) |
+		    FO_PCI_EQ_CTRL_CLR_COVERR);
+	}
+	mtx_unlock_spin(&fmqa->fmqa_mtx);
+	return (FILTER_HANDLED);
+}
+
+static int
+fire_maxslots(device_t dev)
+{
+
+	return (1);
+}
+
+static uint32_t
+fire_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
+    int width)
+{
+
+	return (ofw_pci_read_config_common(dev, PCIE_REGMAX, FO_CONF_OFF(bus,
+	    slot, func, reg), bus, slot, func, reg, width));
+}
+
+static void
+fire_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
+    uint32_t val, int width)
+{
+
+	ofw_pci_write_config_common(dev, PCIE_REGMAX, FO_CONF_OFF(bus, slot,
+	    func, reg), bus, slot, func, reg, val, width);
+}
+
+static int
+fire_route_interrupt(device_t bridge, device_t dev, int pin)
+{
+	ofw_pci_intr_t mintr;
+
+	mintr = ofw_pci_route_interrupt_common(bridge, dev, pin);
+	if (!PCI_INTERRUPT_VALID(mintr))
+		device_printf(bridge,
+		    "could not route pin %d for device %d.%d\n",
+		    pin, pci_get_slot(dev), pci_get_function(dev));
+	return (mintr);
+}
+
+static void
+fire_dmamap_sync(bus_dma_tag_t dt __unused, bus_dmamap_t map,
+    bus_dmasync_op_t op)
+{
+
+	if ((map->dm_flags & DMF_LOADED) == 0)
+		return;
+
+	if ((op & BUS_DMASYNC_POSTREAD) != 0)
+		ofw_pci_dmamap_sync_stst_order_common();
+	else if ((op & BUS_DMASYNC_PREWRITE) != 0)
+		membar(Sync);
+}
+
+static void
+fire_intr_enable(void *arg)
+{
+	struct intr_vector *iv;
+	struct fire_icarg *fica;
+	struct fire_softc *sc;
+	struct pcpu *pc;
+	uint64_t mr;
+	u_int ctrl, i;
+
+	iv = arg;
+	fica = iv->iv_icarg;
+	sc = fica->fica_sc;
+	mr = FO_PCI_IMAP_V;
+	if (sc->sc_mode == FIRE_MODE_OBERON)
+		mr |= (iv->iv_mid << OBERON_PCI_IMAP_T_DESTID_SHFT) &
+		    OBERON_PCI_IMAP_T_DESTID_MASK;
+	else
+		mr |= (iv->iv_mid << FIRE_PCI_IMAP_T_JPID_SHFT) &
+		    FIRE_PCI_IMAP_T_JPID_MASK;
+	/*
+	 * Given that all mondos for the same target are required to use the
+	 * same interrupt controller we just use the CPU ID for indexing the
+	 * latter.
+	 */
+	ctrl = 0;
+	for (i = 0; i < mp_ncpus; ++i) {
+		pc = pcpu_find(i);
+		if (pc == NULL || iv->iv_mid != pc->pc_mid)
+			continue;
+		ctrl = pc->pc_cpuid % 4;
+		break;
+	}
+	mr |= (1ULL << ctrl) << FO_PCI_IMAP_INT_CTRL_NUM_SHFT &
+	    FO_PCI_IMAP_INT_CTRL_NUM_MASK;
+	FIRE_PCI_WRITE_8(sc, fica->fica_map, mr);
+}
+
+static void
+fire_intr_disable(void *arg)
+{
+	struct intr_vector *iv;
+	struct fire_icarg *fica;
+	struct fire_softc *sc;
+
+	iv = arg;
+	fica = iv->iv_icarg;
+	sc = fica->fica_sc;
+	FIRE_PCI_WRITE_8(sc, fica->fica_map,
+	    FIRE_PCI_READ_8(sc, fica->fica_map) & ~FO_PCI_IMAP_V);
+}
+
+static void
+fire_intr_assign(void *arg)
+{
+	struct intr_vector *iv;
+	struct fire_icarg *fica;
+	struct fire_softc *sc;
+	uint64_t mr;
+
+	iv = arg;
+	fica = iv->iv_icarg;
+	sc = fica->fica_sc;
+	mr = FIRE_PCI_READ_8(sc, fica->fica_map);
+	if ((mr & FO_PCI_IMAP_V) != 0) {
+		FIRE_PCI_WRITE_8(sc, fica->fica_map, mr & ~FO_PCI_IMAP_V);
+		FIRE_PCI_BARRIER(sc, fica->fica_map, 8,
+		    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
+	}
+	while (FIRE_PCI_READ_8(sc, fica->fica_clr) != INTCLR_IDLE)
+		;
+	if ((mr & FO_PCI_IMAP_V) != 0)
+		fire_intr_enable(arg);
+}
+
+static void
+fire_intr_clear(void *arg)
+{
+	struct intr_vector *iv;
+	struct fire_icarg *fica;
+
+	iv = arg;
+	fica = iv->iv_icarg;
+	FIRE_PCI_WRITE_8(fica->fica_sc, fica->fica_clr, INTCLR_IDLE);
+}
+
+/*
+ * Given that the event queue implementation matches our current MD and MI
+ * interrupt frameworks like square pegs fit into round holes we are generous
+ * and use one event queue per MSI for now, which limits us to 35 MSIs/MSI-Xs
+ * per Host-PCIe-bridge (we use one event queue for the PCIe error messages).
+ * This seems tolerable as long as most devices just use one MSI/MSI-X anyway.
+ * Adding knowledge about MSIs/MSI-Xs to the MD interrupt code should allow us
+ * to decouple the 1:1 mapping at the cost of no longer being able to bind
+ * MSIs/MSI-Xs to specific CPUs as we currently have no reliable way to
+ * quiesce a device while we move its MSIs/MSI-Xs to another event queue.
+ */
+
+static int
+fire_alloc_msi(device_t dev, device_t child, int count, int maxcount __unused,
+    int *irqs)
+{
+	struct fire_softc *sc;
+	u_int i, j, msiqrun;
+
+	if (powerof2(count) == 0 || count > 32)
+		return (EINVAL);
+
+	sc = device_get_softc(dev);
+	mtx_lock(&sc->sc_msi_mtx);
+	msiqrun = 0;
+	for (i = 0; i < sc->sc_msiq_count; i++) {
+		for (j = i; j < i + count; j++) {
+			if (isclr(sc->sc_msiq_bitmap, j) == 0)
+				break;
+		}
+		if (j == i + count) {
+			msiqrun = i;
+			break;
+		}
+	}
+	if (i == sc->sc_msiq_count) {
+		mtx_unlock(&sc->sc_msi_mtx);
+		return (ENXIO);
+	}
+	for (i = 0; i + count < sc->sc_msi_count; i += count) {
+		for (j = i; j < i + count; j++)
+			if (isclr(sc->sc_msi_bitmap, j) == 0)
+				break;
+		if (j == i + count) {
+			for (j = 0; j < count; j++) {
+				setbit(sc->sc_msiq_bitmap, msiqrun + j);
+				setbit(sc->sc_msi_bitmap, i + j);
+				sc->sc_msi_msiq_table[i + j] = msiqrun + j;
+				irqs[j] = sc->sc_msi_first + i + j;
+			}
+			mtx_unlock(&sc->sc_msi_mtx);
+			return (0);
+		}
+	}
+	mtx_unlock(&sc->sc_msi_mtx);
+	return (ENXIO);
+}
+
+static int
+fire_release_msi(device_t dev, device_t child, int count, int *irqs)
+{
+	struct fire_softc *sc;
+	u_int i;
+
+	sc = device_get_softc(dev);
+	mtx_lock(&sc->sc_msi_mtx);
+	for (i = 0; i < count; i++) {
+		clrbit(sc->sc_msiq_bitmap,
+		    sc->sc_msi_msiq_table[irqs[i] - sc->sc_msi_first]);
+		clrbit(sc->sc_msi_bitmap, irqs[i] - sc->sc_msi_first);
+	}
+	mtx_unlock(&sc->sc_msi_mtx);
+	return (0);
+}
+
+static int
+fire_alloc_msix(device_t dev, device_t child, int *irq)
+{
+	struct fire_softc *sc;
+	int i, msiq;
+
+	sc = device_get_softc(dev);
+	if ((sc->sc_flags & FIRE_MSIX) == 0)
+		return (ENXIO);
+	mtx_lock(&sc->sc_msi_mtx);
+	msiq = 0;
+	for (i = 0; i < sc->sc_msiq_count; i++) {
+		if (isclr(sc->sc_msiq_bitmap, i) != 0) {
+			msiq = i;
+			break;
+		}
+	}
+	if (i == sc->sc_msiq_count) {
+		mtx_unlock(&sc->sc_msi_mtx);
+		return (ENXIO);
+	}
+	for (i = sc->sc_msi_count - 1; i >= 0; i--) {
+		if (isclr(sc->sc_msi_bitmap, i) != 0) {
+			setbit(sc->sc_msiq_bitmap, msiq);
+			setbit(sc->sc_msi_bitmap, i);
+			sc->sc_msi_msiq_table[i] = msiq;
+			*irq = sc->sc_msi_first + i;
+			mtx_unlock(&sc->sc_msi_mtx);
+			return (0);
+		}
+	}
+	mtx_unlock(&sc->sc_msi_mtx);
+	return (ENXIO);
+}
+
+static int
+fire_release_msix(device_t dev, device_t child, int irq)
+{
+	struct fire_softc *sc;
+
+	sc = device_get_softc(dev);
+	if ((sc->sc_flags & FIRE_MSIX) == 0)
+		return (ENXIO);
+	mtx_lock(&sc->sc_msi_mtx);
+	clrbit(sc->sc_msiq_bitmap,
+	    sc->sc_msi_msiq_table[irq - sc->sc_msi_first]);
+	clrbit(sc->sc_msi_bitmap, irq - sc->sc_msi_first);
+	mtx_unlock(&sc->sc_msi_mtx);
+	return (0);
+}
+
+static int
+fire_map_msi(device_t dev, device_t child, int irq, uint64_t *addr,
+    uint32_t *data)
+{
+	struct fire_softc *sc;
+	struct pci_devinfo *dinfo;
+
+	sc = device_get_softc(dev);
+	dinfo = device_get_ivars(child);
+	if (dinfo->cfg.msi.msi_alloc > 0) {
+		if ((irq & ~sc->sc_msi_data_mask) != 0) {
+			device_printf(dev, "invalid MSI 0x%x\n", irq);
+			return (EINVAL);
+		}
+	} else {
+		if ((sc->sc_flags & FIRE_MSIX) == 0)
+			return (ENXIO);
+		if (fls(irq) > sc->sc_msix_data_width) {
+			device_printf(dev, "invalid MSI-X 0x%x\n", irq);
+			return (EINVAL);
+		}
+	}
+	if (dinfo->cfg.msi.msi_alloc > 0 &&
+	    (dinfo->cfg.msi.msi_ctrl & PCIM_MSICTRL_64BIT) == 0)
+		*addr = sc->sc_msi_addr32;
+	else
+		*addr = sc->sc_msi_addr64;
+	*data = irq;
+	return (0);
+}
+
+static void
+fire_msiq_handler(void *cookie)
+{
+	struct intr_vector *iv;
+	struct fire_msiqarg *fmqa;
+
+	iv = cookie;
+	fmqa = iv->iv_icarg;
+	/*
+	 * Note that since fire_intr_clear() will clear the event queue
+	 * interrupt after the handler associated with the MSI [sic] has
+	 * been executed we have to protect the access to the event queue as
+	 * otherwise nested event queue interrupts cause corruption of the
+	 * event queue on MP machines.  Obviously especially when abandoning
+	 * the 1:1 mapping it would be better to not clear the event queue
+	 * interrupt after each handler invocation but only once when the
+	 * outstanding MSIs have been processed but unfortunately that
+	 * doesn't work well and leads to interrupt storms with controllers/
+	 * drivers which don't mask interrupts while the handler is executed.
+	 * Maybe delaying clearing the MSI until after the handler has been
+	 * executed could be used to work around this but that's not the
+	 * intended usage and might in turn cause lost MSIs.
+	 */
+	mtx_lock_spin(&fmqa->fmqa_mtx);
+	fire_msiq_common(iv, fmqa);
+	mtx_unlock_spin(&fmqa->fmqa_mtx);
+}
+
+static void
+fire_msiq_filter(void *cookie)
+{
+	struct intr_vector *iv;
+	struct fire_msiqarg *fmqa;
+
+	iv = cookie;
+	fmqa = iv->iv_icarg;
+	/*
+	 * For filters we don't use fire_intr_clear() since it would clear
+	 * the event queue interrupt while we're still processing the event
+	 * queue as filters and associated post-filter handler are executed
+	 * directly, which in turn would lead to lost MSIs.  So we clear the
+	 * event queue interrupt only once after processing the event queue.
+	 * Given that this still guarantees the filters to not be executed
+	 * concurrently and no other CPU can clear the event queue interrupt
+	 * while the event queue is still processed, we don't even need to
+	 * interlock the access to the event queue in this case.
+	 */
+	critical_enter();
+	fire_msiq_common(iv, fmqa);
+	FIRE_PCI_WRITE_8(fmqa->fmqa_fica.fica_sc, fmqa->fmqa_fica.fica_clr,
+	    INTCLR_IDLE);
+	critical_exit();
+}
+
+static inline void
+fire_msiq_common(struct intr_vector *iv, struct fire_msiqarg *fmqa)
+{
+	struct fire_softc *sc;
+	struct fo_msiq_record *qrec;
+	device_t dev;
+	uint64_t word0;
+	u_int head, msi, msiq;
+
+	sc = fmqa->fmqa_fica.fica_sc;
+	dev = sc->sc_dev;
+	msiq = fmqa->fmqa_msiq;
+	head = (FIRE_PCI_READ_8(sc, fmqa->fmqa_head) & FO_PCI_EQ_HD_MASK) >>
+	    FO_PCI_EQ_HD_SHFT;
+	qrec = &fmqa->fmqa_base[head];
+	word0 = qrec->fomqr_word0;
+	for (;;) {
+		if (__predict_false((word0 & FO_MQR_WORD0_FMT_TYPE_MASK) == 0))
+			break;
+		KASSERT((word0 & FO_MQR_WORD0_FMT_TYPE_MSI64) != 0 ||
+		    (word0 & FO_MQR_WORD0_FMT_TYPE_MSI32) != 0,
+		    ("%s: received non-MSI/MSI-X message in event queue %d "
+		    "(word0 %#llx)", device_get_nameunit(dev), msiq,
+		    (unsigned long long)word0));
+		msi = (word0 & FO_MQR_WORD0_DATA0_MASK) >>
+		    FO_MQR_WORD0_DATA0_SHFT;
+		/*
+		 * Sanity check the MSI/MSI-X as long as we use a 1:1 mapping.
+		 */
+		KASSERT(msi == fmqa->fmqa_msi,
+		    ("%s: received non-matching MSI/MSI-X in event queue %d "
+		    "(%d versus %d)", device_get_nameunit(dev), msiq, msi,
+		    fmqa->fmqa_msi));
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_CLR_BASE + (msi << 3),
+		    FO_PCI_MSI_CLR_EQWR_N);
+		if (__predict_false(intr_event_handle(iv->iv_event,
+		    NULL) != 0))
+			printf("stray MSI/MSI-X in event queue %d\n", msiq);
+		qrec->fomqr_word0 &= ~FO_MQR_WORD0_FMT_TYPE_MASK;
+		head = (head + 1) % sc->sc_msiq_size;
+		qrec = &fmqa->fmqa_base[head];
+		word0 = qrec->fomqr_word0;
+	}
+	FIRE_PCI_WRITE_8(sc, fmqa->fmqa_head, (head & FO_PCI_EQ_HD_MASK) <<
+	    FO_PCI_EQ_HD_SHFT);
+	if (__predict_false((FIRE_PCI_READ_8(sc, fmqa->fmqa_tail) &
+	    FO_PCI_EQ_TL_OVERR) != 0)) {
+		device_printf(dev, "event queue %d overflow\n", msiq);
+		msiq <<= 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + msiq,
+		    FIRE_PCI_READ_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + msiq) |
+		    FO_PCI_EQ_CTRL_CLR_COVERR);
+	}
+}
+
+static int
+fire_setup_intr(device_t dev, device_t child, struct resource *ires,
+    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
+    void **cookiep)
+{
+	struct fire_softc *sc;
+	struct fire_msiqarg *fmqa;
+	u_long vec;
+	int error;
+	u_int msi, msiq;
+
+	sc = device_get_softc(dev);
+	/*
+	 * XXX this assumes that a device only has one INTx, while in fact
+	 * Cassini+ and Saturn can use all four the firmware has assigned
+	 * to them, but so does pci(4).
+	 */
+	if (rman_get_rid(ires) != 0) {
+		msi = rman_get_start(ires);
+		msiq = sc->sc_msi_msiq_table[msi - sc->sc_msi_first];
+		vec = INTMAP_VEC(sc->sc_ign, sc->sc_msiq_ino_first + msiq);
+		msiq += sc->sc_msiq_first;
+		if (intr_vectors[vec].iv_ic != &fire_ic) {
+			device_printf(dev,
+			    "invalid interrupt controller for vector 0x%lx\n",
+			    vec);
+			return (EINVAL);
+		}
+		/*
+		 * The MD interrupt code needs the vector rather than the MSI.
+		 */
+		rman_set_start(ires, vec);
+		rman_set_end(ires, vec);
+		error = bus_generic_setup_intr(dev, child, ires, flags, filt,
+		    intr, arg, cookiep);
+		rman_set_start(ires, msi);
+		rman_set_end(ires, msi);
+		if (error != 0)
+			return (error);
+		fmqa = intr_vectors[vec].iv_icarg;
+		/*
+		 * XXX inject our event queue handler.
+		 */
+		if (filt != NULL) {
+			intr_vectors[vec].iv_func = fire_msiq_filter;
+			intr_vectors[vec].iv_ic = &fire_msiqc_filter;
+			/*
+			 * Ensure the event queue interrupt is cleared, it
+			 * might have triggered before.  Given we supply NULL
+			 * as ic_clear, inthand_add() won't do this for us.
+			 */
+			FIRE_PCI_WRITE_8(sc, fmqa->fmqa_fica.fica_clr,
+			    INTCLR_IDLE);
+		} else
+			intr_vectors[vec].iv_func = fire_msiq_handler;
+		/* Record the MSI/MSI-X as long as we we use a 1:1 mapping. */
+		fmqa->fmqa_msi = msi;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_SET_BASE + (msiq << 3),
+		    FO_PCI_EQ_CTRL_SET_EN);
+		msi <<= 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_MAP_BASE + msi,
+		    (FIRE_PCI_READ_8(sc, FO_PCI_MSI_MAP_BASE + msi) &
+		    ~FO_PCI_MSI_MAP_EQNUM_MASK) |
+		    ((msiq << FO_PCI_MSI_MAP_EQNUM_SHFT) &
+		    FO_PCI_MSI_MAP_EQNUM_MASK));
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_CLR_BASE + msi,
+		    FO_PCI_MSI_CLR_EQWR_N);
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_MAP_BASE + msi,
+		    FIRE_PCI_READ_8(sc, FO_PCI_MSI_MAP_BASE + msi) |
+		    FO_PCI_MSI_MAP_V);
+		return (error);
+	}
+
+	/*
+	 * Make sure the vector is fully specified and we registered
+	 * our interrupt controller for it.
+	 */
+	vec = rman_get_start(ires);
+	if (INTIGN(vec) != sc->sc_ign) {
+		device_printf(dev, "invalid interrupt vector 0x%lx\n", vec);
+		return (EINVAL);
+	}
+	if (intr_vectors[vec].iv_ic != &fire_ic) {
+		device_printf(dev,
+		    "invalid interrupt controller for vector 0x%lx\n", vec);
+		return (EINVAL);
+	}
+	return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr,
+	    arg, cookiep));
+}
+
+static int
+fire_teardown_intr(device_t dev, device_t child, struct resource *ires,
+    void *cookie)
+{
+	struct fire_softc *sc;
+	u_long vec;
+	int error;
+	u_int msi, msiq;
+
+	sc = device_get_softc(dev);
+	if (rman_get_rid(ires) != 0) {
+		msi = rman_get_start(ires);
+		msiq = sc->sc_msi_msiq_table[msi - sc->sc_msi_first];
+		vec = INTMAP_VEC(sc->sc_ign, msiq + sc->sc_msiq_ino_first);
+		msiq += sc->sc_msiq_first;
+		msi <<= 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_MAP_BASE + msi,
+		    FIRE_PCI_READ_8(sc, FO_PCI_MSI_MAP_BASE + msi) &
+		    ~FO_PCI_MSI_MAP_V);
+		msiq <<= 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + msiq,
+		    FO_PCI_EQ_CTRL_CLR_COVERR | FO_PCI_EQ_CTRL_CLR_E2I |
+		    FO_PCI_EQ_CTRL_CLR_DIS);
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_TL_BASE + msiq,
+		    (0 << FO_PCI_EQ_TL_SHFT) & FO_PCI_EQ_TL_MASK);
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_HD_BASE + msiq,
+		    (0 << FO_PCI_EQ_HD_SHFT) & FO_PCI_EQ_HD_MASK);
+		intr_vectors[vec].iv_ic = &fire_ic;
+		/*
+		 * The MD interrupt code needs the vector rather than the MSI.
+		 */
+		rman_set_start(ires, vec);
+		rman_set_end(ires, vec);
+		error = bus_generic_teardown_intr(dev, child, ires, cookie);
+		msi >>= 3;
+		rman_set_start(ires, msi);
+		rman_set_end(ires, msi);
+		return (error);
+	}
+	return (bus_generic_teardown_intr(dev, child, ires, cookie));
+}
+
+static struct resource *
+fire_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct fire_softc *sc;
+
+	if (type == SYS_RES_IRQ && *rid == 0) {
+		sc = device_get_softc(bus);
+		start = end = INTMAP_VEC(sc->sc_ign, end);
+	}
+	return (ofw_pci_alloc_resource(bus, child, type, rid, start, end,
+	    count, flags));
+}
+
+static u_int
+fire_get_timecount(struct timecounter *tc)
+{
+	struct fire_softc *sc;
+
+	sc = tc->tc_priv;
+	return (FIRE_CTRL_READ_8(sc, FO_XBC_PRF_CNT0) & TC_COUNTER_MAX_MASK);
+}


Property changes on: trunk/sys/sparc64/pci/fire.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/firereg.h
===================================================================
--- trunk/sys/sparc64/pci/firereg.h	                        (rev 0)
+++ trunk/sys/sparc64/pci/firereg.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,1011 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Marius Strobl <marius at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/pci/firereg.h 292789 2015-12-27 19:37:47Z marius $
+ */
+
+#ifndef _SPARC64_PCI_FIREREG_H_
+#define	_SPARC64_PCI_FIREREG_H_
+
+#define	FIRE_NINTR				3	/* 2 OFW + 1 MSIq */
+#define	FIRE_NREG				2
+
+#define	FIRE_PCI				0
+#define	FIRE_CTRL				1
+
+/* PCI configuration and status registers */
+#define	FO_PCI_INT_MAP_BASE			0x01000
+#define	FO_PCI_INT_CLR_BASE			0x01400
+#define	FO_PCI_EQ_BASE_ADDR			0x10000
+#define	FO_PCI_EQ_CTRL_SET_BASE			0x11000
+#define	FO_PCI_EQ_CTRL_CLR_BASE			0x11200
+#define	FO_PCI_EQ_TL_BASE			0x11600
+#define	FO_PCI_EQ_HD_BASE			0x11800
+#define	FO_PCI_MSI_MAP_BASE			0x20000
+#define	FO_PCI_MSI_CLR_BASE			0x28000
+#define	FO_PCI_ERR_COR				0x30000
+#define	FO_PCI_ERR_NONFATAL			0x30008
+#define	FO_PCI_ERR_FATAL			0x30010
+#define	FO_PCI_PM_PME				0x30018
+#define	FO_PCI_PME_TO_ACK			0x30020
+#define	FO_PCI_IMU_INT_EN			0x31008
+#define	FO_PCI_IMU_INT_STAT			0x31010
+#define	FO_PCI_IMU_ERR_STAT_CLR			0x31018
+#define	FO_PCI_IMU_RDS_ERR_LOG			0x31028
+#define	FO_PCI_IMU_SCS_ERR_LOG			0x31030
+#define	FO_PCI_IMU_EQS_ERR_LOG			0x31038
+#define	FO_PCI_DMC_CORE_BLOCK_INT_EN		0x31800
+#define	FO_PCI_DMC_CORE_BLOCK_ERR_STAT		0x31808
+#define	FO_PCI_MULTI_CORE_ERR_STAT		0x31810
+#define	FO_PCI_MSI_32_BIT_ADDR			0x34000
+#define	FO_PCI_MSI_64_BIT_ADDR			0x34008
+#define	FO_PCI_MMU				0x40000
+#define	FO_PCI_MMU_INT_EN			0x41008
+#define	FO_PCI_MMU_INT_STAT			0x41010
+#define	FO_PCI_MMU_ERR_STAT_CLR			0x41018
+#define	FO_PCI_MMU_TRANS_FAULT_ADDR		0x41028
+#define	FO_PCI_MMU_TRANS_FAULT_STAT		0x41030
+#define	FO_PCI_ILU_INT_EN			0x51008
+#define	FO_PCI_ILU_INT_STAT			0x51010
+#define	FO_PCI_ILU_ERR_STAT_CLR			0x51018
+#define	FO_PCI_DMC_DBG_SEL_PORTA		0x53000
+#define	FO_PCI_DMC_DBG_SEL_PORTB		0x53008
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN		0x51800
+#define	FO_PCI_PEC_CORE_BLOCK_INT_STAT		0x51808
+#define	FO_PCI_TLU_CTRL				0x80000
+#define	FO_PCI_TLU_OEVENT_INT_EN		0x81008
+#define	FO_PCI_TLU_OEVENT_INT_STAT		0x81010
+#define	FO_PCI_TLU_OEVENT_STAT_CLR		0x81018
+#define	FO_PCI_TLU_RX_OEVENT_HDR1_LOG		0x81028
+#define	FO_PCI_TLU_RX_OEVENT_HDR2_LOG		0x81030
+#define	FO_PCI_TLU_TX_OEVENT_HDR1_LOG		0x81038
+#define	FO_PCI_TLU_TX_OEVENT_HDR2_LOG		0x81040
+#define	FO_PCI_TLU_DEV_CTRL			0x90008
+#define	FO_PCI_TLU_LNK_CTRL			0x90020
+#define	FO_PCI_TLU_LNK_STAT			0x90028
+#define	FO_PCI_TLU_UERR_INT_EN			0x91008
+#define	FO_PCI_TLU_UERR_INT_STAT		0x91010
+#define	FO_PCI_TLU_UERR_STAT_CLR		0x91018
+#define	FO_PCI_TLU_RX_UERR_HDR1_LOG		0x91028
+#define	FO_PCI_TLU_RX_UERR_HDR2_LOG		0x91030
+#define	FO_PCI_TLU_TX_UERR_HDR1_LOG		0x91038
+#define	FO_PCI_TLU_TX_UERR_HDR2_LOG		0x91040
+#define	FO_PCI_TLU_CERR_INT_EN			0xa1008
+#define	FO_PCI_TLU_CERR_INT_STAT		0xa1010
+#define	FO_PCI_TLU_CERR_STAT_CLR		0xa1018
+#define	FO_PCI_LPU_RST				0xe2008
+#define	FO_PCI_LPU_INT_STAT			0xe2040
+#define	FO_PCI_LPU_INT_MASK			0xe0248
+#define	FO_PCI_LPU_LNK_LYR_CFG			0xe2200
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT		0xe2210
+#define	FO_PCI_LPU_FLW_CTRL_UPDT_CTRL		0xe2240
+#define	FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS	0xe2400
+#define	FO_PCI_LPU_TXLNK_RPLY_TMR_THRS		0xe2410
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR		0xe2430
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT		0xe2610
+#define	FO_PCI_LPU_LTSSM_CFG2			0xe2788
+#define	FO_PCI_LPU_LTSSM_CFG3			0xe2790
+#define	FO_PCI_LPU_LTSSM_CFG4			0xe2798
+#define	FO_PCI_LPU_LTSSM_CFG5			0xe27a0
+
+/* PCI interrupt mapping registers */
+#define	FO_PCI_IMAP_MDO_MODE			0x8000000000000000ULL
+#define	FO_PCI_IMAP_V				0x0000000080000000ULL
+#define	FIRE_PCI_IMAP_T_JPID_MASK		0x000000007c000000ULL
+#define	FIRE_PCI_IMAP_T_JPID_SHFT		26
+#define	OBERON_PCI_IMAP_T_DESTID_MASK		0x000000007fe00000ULL
+#define	OBERON_PCI_IMAP_T_DESTID_SHFT		21
+#define	FO_PCI_IMAP_INT_CTRL_NUM_MASK		0x00000000000003c0ULL
+#define	FO_PCI_IMAP_INT_CTRL_NUM_SHFT		6
+
+/* PCI interrupt clear registers - use INTCLR_* from <machine/bus_common.h> */
+
+/* PCI event queue base address register */
+#define	FO_PCI_EQ_BASE_ADDR_BYPASS		0xfffc000000000000ULL
+#define	FO_PCI_EQ_BASE_ADDR_MASK		0xfffffffffff80000ULL
+#define	FO_PCI_EQ_BASE_ADDR_SHFT		19
+
+/* PCI event queue control set registers */
+#define	FO_PCI_EQ_CTRL_SET_ENOVERR		0x0200000000000000ULL
+#define	FO_PCI_EQ_CTRL_SET_EN			0x0000100000000000ULL
+
+/* PCI event queue control clear registers */
+#define	FO_PCI_EQ_CTRL_CLR_COVERR		0x0200000000000000ULL
+#define	FO_PCI_EQ_CTRL_CLR_E2I			0x0000800000000000ULL
+#define	FO_PCI_EQ_CTRL_CLR_DIS			0x0000100000000000ULL
+
+/* PCI event queue tail registers */
+#define	FO_PCI_EQ_TL_OVERR			0x0200000000000000ULL
+#define	FO_PCI_EQ_TL_MASK			0x000000000000007fULL
+#define	FO_PCI_EQ_TL_SHFT			0
+
+/* PCI event queue head registers */
+#define	FO_PCI_EQ_HD_MASK			0x000000000000007fULL
+#define	FO_PCI_EQ_HD_SHFT			0
+
+/* PCI MSI mapping registers */
+#define	FO_PCI_MSI_MAP_V			0x8000000000000000ULL
+#define	FO_PCI_MSI_MAP_EQWR_N			0x4000000000000000ULL
+#define	FO_PCI_MSI_MAP_EQNUM_MASK		0x000000000000003fULL
+#define	FO_PCI_MSI_MAP_EQNUM_SHFT		0
+
+/* PCI MSI clear registers */
+#define	FO_PCI_MSI_CLR_EQWR_N			0x4000000000000000ULL
+
+/*
+ * PCI IMU interrupt enable, interrupt status and error status clear
+ * registers
+ */
+#define	FO_PCI_IMU_ERR_INT_SPARE_S_MASK		0x00007c0000000000ULL
+#define	FO_PCI_IMU_ERR_INT_SPARE_S_SHFT		42
+#define	FO_PCI_IMU_ERR_INT_EQ_OVER_S		0x0000020000000000ULL
+#define	FO_PCI_IMU_ERR_INT_EQ_NOT_EN_S		0x0000010000000000ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_MAL_ERR_S	0x0000008000000000ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_PAR_ERR_S	0x0000004000000000ULL
+#define	FO_PCI_IMU_ERR_INT_PMEACK_MES_NOT_EN_S	0x0000002000000000ULL
+#define	FO_PCI_IMU_ERR_INT_PMPME_MES_NOT_EN_S	0x0000001000000000ULL
+#define	FO_PCI_IMU_ERR_INT_FATAL_MES_NOT_EN_S	0x0000000800000000ULL
+#define	FO_PCI_IMU_ERR_INT_NFATAL_MES_NOT_EN_S	0x0000000400000000ULL
+#define	FO_PCI_IMU_ERR_INT_COR_MES_NOT_EN_S	0x0000000200000000ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_NOT_EN_S		0x0000000100000000ULL
+#define	FO_PCI_IMU_ERR_INT_SPARE_P_MASK		0x0000000000007c00ULL
+#define	FO_PCI_IMU_ERR_INT_SPARE_P_SHFT		10
+#define	FO_PCI_IMU_ERR_INT_EQ_OVER_P		0x0000000000000200ULL
+#define	FO_PCI_IMU_ERR_INT_EQ_NOT_EN_P		0x0000000000000100ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_MAL_ERR_P	0x0000000000000080ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_PAR_ERR_P	0x0000000000000040ULL
+#define	FO_PCI_IMU_ERR_INT_PMEACK_MES_NOT_EN_P	0x0000000000000020ULL
+#define	FO_PCI_IMU_ERR_INT_PMPME_MES_NOT_EN_P	0x0000000000000010ULL
+#define	FO_PCI_IMU_ERR_INT_FATAL_MES_NOT_EN_P	0x0000000000000008ULL
+#define	FO_PCI_IMU_ERR_INT_NFATAL_MES_NOT_EN_P	0x0000000000000004ULL
+#define	FO_PCI_IMU_ERR_INT_COR_MES_NOT_EN_P	0x0000000000000002ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_NOT_EN_P		0x0000000000000001ULL
+
+/* PCI IMU RDS error log register */
+#define	FO_PCI_IMU_RDS_ERR_LOG_TYPE_MASK	0xfc00000000000000ULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_TYPE_SHFT	58
+#define	FO_PCI_IMU_RDS_ERR_LOG_LENGTH_MASK	0x03ff000000000000ULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_LENGTH_SHFT	48
+#define	FO_PCI_IMU_RDS_ERR_LOG_REQ_ID_MASK	0x0000ffff00000000ULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_REQ_ID_SHFT	32
+#define	FO_PCI_IMU_RDS_ERR_LOG_TLP_TAG_MASK	0x00000000ff000000ULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_TLP_TAG_SHFT	24
+#define	FO_PCI_IMU_RDS_ERR_LOG_BE_MCODE_MASK	0x0000000000ff0000ULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_BE_MCODE_SHFT	16
+#define	FO_PCI_IMU_RDS_ERR_LOG_MSI_DATA_MASK	0x000000000000ffffULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_MSI_DATA_SHFT	0
+
+/* PCI IMU SCS error log register */
+#define	FO_PCI_IMU_SCS_ERR_LOG_TYPE_MASK	0xfc00000000000000ULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_TYPE_SHFT	58
+#define	FO_PCI_IMU_SCS_ERR_LOG_LENGTH_MASK	0x03ff000000000000ULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_LENGTH_SHFT	48
+#define	FO_PCI_IMU_SCS_ERR_LOG_REQ_ID_MASK	0x0000ffff00000000ULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_REQ_ID_SHFT	32
+#define	FO_PCI_IMU_SCS_ERR_LOG_TLP_TAG_MASK	0x00000000ff000000ULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_TLP_TAG_SHFT	24
+#define	FO_PCI_IMU_SCS_ERR_LOG_BE_MODE_MASK	0x0000000000ff0000ULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_BE_MCODE_SHFT	16
+#define	FO_PCI_IMU_SCS_ERR_LOG_EQ_NUM_MASK	0x000000000000003fULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_EQ_NUM_SHFT	0
+
+/* PCI IMU EQS error log register */
+#define	FO_PCI_IMU_EQS_ERR_LOG_EQ_NUM_MASK	0x000000000000003fULL
+#define	FO_PCI_IMU_EQS_ERROR_LOG_EQ_NUM_SHFT	0
+
+/*
+ * PCI ERR COR, ERR NONFATAL, ERR FATAL, PM PME and PME To ACK mapping
+ * registers
+ */
+#define	FO_PCI_ERR_PME_V			0x8000000000000000ULL
+#define	FO_PCI_ERR_PME_EQNUM_MASK		0x000000000000003fULL
+#define	FO_PCI_ERR_PME_EQNUM_SHFT		0
+
+/* PCI DMC core and block interrupt enable register */
+#define	FO_PCI_DMC_CORE_BLOCK_INT_EN_DMC	0x8000000000000000ULL
+#define	FO_PCI_DMC_CORE_BLOCK_INT_EN_MMU	0x0000000000000002ULL
+#define	FO_PCI_DMC_CORE_BLOCK_INT_EN_IMU	0x0000000000000001ULL
+
+/* PCI DMC core and block error status register */
+#define	FO_PCI_DMC_CORE_BLOCK_ERR_STAT_MMU	0x0000000000000002ULL
+#define	FO_PCI_DMC_CORE_BLOCK_ERR_STAT_IMU	0x0000000000000001ULL
+
+/* PCI multi core error status register */
+#define	FO_PCI_MULTI_CORE_ERR_STAT_PEC		0x0000000000000002ULL
+#define	FO_PCI_MULTI_CORE_ERR_STAT_DMC		0x0000000000000001ULL
+
+/* PCI MSI 32-bit address register */
+#define	FO_PCI_MSI_32_BIT_ADDR_MASK		0x00000000ffff0000ULL
+#define	FO_PCI_MSI_32_BIT_ADDR_SHFT		16
+
+/* PCI MSI 64-bit address register */
+#define	FO_PCI_MSI_64_BIT_ADDR_MASK		0x0000ffffffff0000ULL
+#define	FO_PCI_MSI_64_BIT_ADDR_SHFT		16
+
+/*
+ * PCI MMU interrupt enable, interrupt status and error status clear
+ * registers
+ */
+#define	FO_PCI_MMU_ERR_INT_S_MASK		0x0000ffff00000000ULL
+#define	FO_PCI_MMU_ERR_INT_S_SHFT		32
+#define	FO_PCI_MMU_ERR_INT_TBW_DPE_S		0x0000800000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_ERR_S		0x0000400000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_UDE_S		0x0000200000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_DME_S		0x0000100000000000ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE3_S		0x0000080000000000ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE2_S		0x0000040000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TTC_CAE_S		0x0000020000000000ULL
+#define	FIRE_PCI_MMU_ERR_INT_TTC_DPE_S		0x0000010000000000ULL
+#define	OBERON_PCI_MMU_ERR_INT_TTC_DUE_S	0x0000010000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TTE_PRT_S		0x0000008000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TTE_INV_S		0x0000004000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TRN_OOR_S		0x0000002000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TRN_ERR_S		0x0000001000000000ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE1_S		0x0000000800000000ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE0_S		0x0000000400000000ULL
+#define	FO_PCI_MMU_ERR_INT_BYP_OOR_S		0x0000000200000000ULL
+#define	FO_PCI_MMU_ERR_INT_BYP_ERR_S		0x0000000100000000ULL
+#define	FO_PCI_MMU_ERR_INT_P_MASK		0x000000000000ffffULL
+#define	FO_PCI_MMU_ERR_INT_P_SHFT		0
+#define	FO_PCI_MMU_ERR_INT_TBW_DPE_P		0x0000000000008000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_ERR_P		0x0000000000004000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_UDE_P		0x0000000000002000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_DME_P		0x0000000000001000ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE3_P		0x0000000000000800ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE2_P		0x0000000000000400ULL
+#define	FO_PCI_MMU_ERR_INT_TTC_CAE_P		0x0000000000000200ULL
+#define	FIRE_PCI_MMU_ERR_INT_TTC_DPE_P		0x0000000000000100ULL
+#define	OBERON_PCI_MMU_ERR_INT_TTC_DUE_P	0x0000000000000100ULL
+#define	FO_PCI_MMU_ERR_INT_TTE_PRT_P		0x0000000000000080ULL
+#define	FO_PCI_MMU_ERR_INT_TTE_INV_P		0x0000000000000040ULL
+#define	FO_PCI_MMU_ERR_INT_TRN_OOR_P		0x0000000000000020ULL
+#define	FO_PCI_MMU_ERR_INT_TRN_ERR_P		0x0000000000000010ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE1_P		0x0000000000000008ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE0_P		0x0000000000000004ULL
+#define	FO_PCI_MMU_ERR_INT_BYP_OOR_P		0x0000000000000002ULL
+#define	FO_PCI_MMU_ERR_INT_BYP_ERR_P		0x0000000000000001ULL
+
+/* PCI MMU translation fault address register */
+#define	FO_PCI_MMU_TRANS_FAULT_ADDR_VA_MASK	0xfffffffffffffffcULL
+#define	FO_PCI_MMU_TRANS_FAULT_ADDR_VA_SHFT	2
+
+/* PCI MMU translation fault status register */
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_ENTRY_MASK	0x000001ff00000000ULL
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_ENTRY_SHFT	32
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_TYPE_MASK	0x00000000007f0000ULL
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_TYPE_SHFT	16
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_ID_MASK	0x000000000000ffffULL
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_ID_SHFT	0
+
+/*
+ * PCI ILU interrupt enable, interrupt status and error status clear
+ * registers
+ */
+#define	FO_PCI_ILU_ERR_INT_SPARE3_S		0x0000008000000000ULL
+#define	FO_PCI_ILU_ERR_INT_SPARE2_S		0x0000004000000000ULL
+#define	FO_PCI_ILU_ERR_INT_SPARE1_S		0x0000002000000000ULL
+#define	FIRE_PCI_ILU_ERR_INT_IHB_PE_S		0x0000001000000000ULL
+#define	OBERON_PCI_ILU_ERR_INT_IHB_UE_S		0x0000001000000000ULL
+#define	FO_PCI_ILU_ERR_INT_SPARE3_P		0x0000000000000080ULL
+#define	FO_PCI_ILU_ERR_INT_SPARE2_P		0x0000000000000040ULL
+#define	FO_PCI_ILU_ERR_INT_SPARE1_P		0x0000000000000020ULL
+#define	FIRE_PCI_ILU_ERR_INT_IHB_PE_P		0x0000000000000010ULL
+#define	OBERON_PCI_ILU_ERR_INT_IHB_UE_P		0x0000000000000010ULL
+
+/* PCI DMC debug select registers for port a/b */
+#define	FO_PCI_DMC_DBG_SEL_PORT_BLCK_MASK	0x00000000000003c0ULL
+#define	FO_PCI_DMC_DBG_SEL_PORT_BLCK_SHFT	6
+#define	FO_PCI_DMC_DBG_SEL_PORT_SUB_MASK	0x0000000000000038ULL
+#define	FO_PCI_DMC_DBG_SEL_PORT_SUB_SHFT	3
+#define	FO_PCI_DMC_DBG_SEL_PORT_SUB_SGNL_MASK	0x0000000000000007ULL
+#define	FO_PCI_DMC_DBG_SEL_PORT_SUB_SGNL_SHFT	0
+
+/* PCI PEC core and block interrupt enable register */
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN_PEC	0x8000000000000000ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN_ILU	0x0000000000000008ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN_UERR	0x0000000000000004ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN_CERR	0x0000000000000002ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN_OEVENT	0x0000000000000001ULL
+
+/* PCI PEC core and block interrupt status register */
+#define	FO_PCI_PEC_CORE_BLOCK_INT_STAT_ILU	0x0000000000000008ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_STAT_UERR	0x0000000000000004ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_STAT_CERR	0x0000000000000002ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_STAT_OEVENT	0x0000000000000001ULL
+
+/* PCI TLU control register */
+#define	FO_PCI_TLU_CTRL_L0S_TIM_MASK		0x00000000ff000000ULL
+#define	FO_PCI_TLU_CTRL_L0S_TIM_SHFT		24
+#define	FO_PCI_TLU_CTRL_NWPR_EN			0x0000000000100000ULL
+#define	FO_PCI_TLU_CTRL_CTO_SEL_MASK		0x0000000000070000ULL
+#define	FO_PCI_TLU_CTRL_CTO_SEL_SHFT		16
+#define	FO_PCI_TLU_CTRL_CFG_MASK		0x000000000000ffffULL
+#define	FO_PCI_TLU_CTRL_CFG_SHFT		0
+#define	FO_PCI_TLU_CTRL_CFG_REMAIN_DETECT_QUIET	0x0000000000000100ULL
+#define	FO_PCI_TLU_CTRL_CFG_PAD_LOOPBACK_EN	0x0000000000000080ULL
+#define	FO_PCI_TLU_CTRL_CFG_EWRAP_LOOPBACK_EN	0x0000000000000040ULL
+#define	FO_PCI_TLU_CTRL_CFG_DIGITAL_LOOPBACK_EN	0x0000000000000020ULL
+#define	FO_PCI_TLU_CTRL_CFG_MPS_MASK		0x000000000000001cULL
+#define	FO_PCI_TLU_CTRL_CFG_MPS_SHFT		2
+#define	FO_PCI_TLU_CTRL_CFG_COMMON_CLK_CFG	0x0000000000000002ULL
+#define	FO_PCI_TLU_CTRL_CFG_PORT		0x0000000000000001ULL
+
+/*
+ * PCI TLU other event interrupt enable, interrupt status and status clear
+ * registers
+ */
+#define	FO_PCI_TLU_OEVENT_S_MASK		0x00ffffff00000000ULL
+#define	FO_PCI_TLU_OEVENT_S_SHFT		32
+#define	FO_PCI_TLU_OEVENT_SPARE_S		0x0080000000000000ULL
+#define	FO_PCI_TLU_OEVENT_MFC_S			0x0040000000000000ULL
+#define	FO_PCI_TLU_OEVENT_CTO_S			0x0020000000000000ULL
+#define	FO_PCI_TLU_OEVENT_NFP_S			0x0010000000000000ULL
+#define	FO_PCI_TLU_OEVENT_LWC_S			0x0008000000000000ULL
+#define	FO_PCI_TLU_OEVENT_MRC_S			0x0004000000000000ULL
+#define	FO_PCI_TLU_OEVENT_WUC_S			0x0002000000000000ULL
+#define	FO_PCI_TLU_OEVENT_RUC_S			0x0001000000000000ULL
+#define	FO_PCI_TLU_OEVENT_CRS_S			0x0000800000000000ULL
+#define	FO_PCI_TLU_OEVENT_IIP_S			0x0000400000000000ULL
+#define	FO_PCI_TLU_OEVENT_EDP_S			0x0000200000000000ULL
+#define	FIRE_PCI_TLU_OEVENT_EHP_S		0x0000100000000000ULL
+#define	OBERON_PCI_TLU_OEVENT_EHBUE_S		0x0000100000000000ULL
+#define	OBERON_PCI_TLU_OEVENT_EDBUE_S		0x0000100000000000ULL
+#define	FO_PCI_TLU_OEVENT_LIN_S			0x0000080000000000ULL
+#define	FO_PCI_TLU_OEVENT_LRS_S			0x0000040000000000ULL
+#define	FO_PCI_TLU_OEVENT_LDN_S			0x0000020000000000ULL
+#define	FO_PCI_TLU_OEVENT_LUP_S			0x0000010000000000ULL
+#define	FO_PCI_TLU_OEVENT_LPU_S_MASK		0x000000c000000000ULL
+#define	FO_PCI_TLU_OEVENT_LPU_S_SHFT		38
+#define	OBERON_PCI_TLU_OEVENT_TLUEITMO_S	0x0000008000000000ULL
+#define	FO_PCI_TLU_OEVENT_ERU_S			0x0000002000000000ULL
+#define	FO_PCI_TLU_OEVENT_ERO_S			0x0000001000000000ULL
+#define	FO_PCI_TLU_OEVENT_EMP_S			0x0000000800000000ULL
+#define	FO_PCI_TLU_OEVENT_EPE_S			0x0000000400000000ULL
+#define	FIRE_PCI_TLU_OEVENT_ERP_S		0x0000000200000000ULL
+#define	OBERON_PCI_TLU_OEVENT_ERBU_S		0x0000000200000000ULL
+#define	FIRE_PCI_TLU_OEVENT_EIP_S		0x0000000100000000ULL
+#define	OBERON_PCI_TLU_OEVENT_EIUE_S		0x0000000100000000ULL
+#define	FO_PCI_TLU_OEVENT_P_MASK		0x0000000000ffffffULL
+#define	FO_PCI_TLU_OEVENT_P_SHFT		0
+#define	FO_PCI_TLU_OEVENT_SPARE_P		0x0000000000800000ULL
+#define	FO_PCI_TLU_OEVENT_MFC_P			0x0000000000400000ULL
+#define	FO_PCI_TLU_OEVENT_CTO_P			0x0000000000200000ULL
+#define	FO_PCI_TLU_OEVENT_NFP_P			0x0000000000100000ULL
+#define	FO_PCI_TLU_OEVENT_LWC_P			0x0000000000080000ULL
+#define	FO_PCI_TLU_OEVENT_MRC_P			0x0000000000040000ULL
+#define	FO_PCI_TLU_OEVENT_WUC_P			0x0000000000020000ULL
+#define	FO_PCI_TLU_OEVENT_RUC_P			0x0000000000010000ULL
+#define	FO_PCI_TLU_OEVENT_CRS_P			0x0000000000008000ULL
+#define	FO_PCI_TLU_OEVENT_IIP_P			0x0000000000004000ULL
+#define	FO_PCI_TLU_OEVENT_EDP_P			0x0000000000002000ULL
+#define	FIRE_PCI_TLU_OEVENT_EHP_P		0x0000000000001000ULL
+#define	OBERON_PCI_TLU_OEVENT_EHBUE_P		0x0000000000001000ULL
+#define	OBERON_PCI_TLU_OEVENT_EDBUE_P		0x0000000000001000ULL
+#define	FO_PCI_TLU_OEVENT_LIN_P			0x0000000000000800ULL
+#define	FO_PCI_TLU_OEVENT_LRS_P			0x0000000000000400ULL
+#define	FO_PCI_TLU_OEVENT_LDN_P			0x0000000000000200ULL
+#define	FO_PCI_TLU_OEVENT_LUP_P			0x0000000000000100ULL
+#define	FO_PCI_TLU_OEVENT_LPU_P_MASK		0x00000000000000c0ULL
+#define	FO_PCI_TLU_OEVENT_LPU_P_SHFT		6
+#define	OBERON_PCI_TLU_OEVENT_TLUEITMO_P	0x0000000000000080ULL
+#define	FO_PCI_TLU_OEVENT_ERU_P			0x0000000000000020ULL
+#define	FO_PCI_TLU_OEVENT_ERO_P			0x0000000000000010ULL
+#define	FO_PCI_TLU_OEVENT_EMP_P			0x0000000000000008ULL
+#define	FO_PCI_TLU_OEVENT_EPE_P			0x0000000000000004ULL
+#define	FIRE_PCI_TLU_OEVENT_ERP_P		0x0000000000000002ULL
+#define	OBERON_PCI_TLU_OEVENT_ERBU_P		0x0000000000000002ULL
+#define	FIRE_PCI_TLU_OEVENT_EIP_P		0x0000000000000001ULL
+#define	OBERON_PCI_TLU_OEVENT_EIUE_P		0x0000000000000001ULL
+
+/* PCI receive/transmit DLU/TLU other event header 1/2 log registers */
+#define	FO_PCI_TLU_OEVENT_HDR_LOG_MASK		0xffffffffffffffffULL
+#define	FO_PCI_TLU_OEVENT_HDR_LOG_SHFT		0
+
+/* PCI TLU device control register */
+#define	FO_PCI_TLU_DEV_CTRL_MRRS_MASK		0x0000000000007000ULL
+#define	FO_PCI_TLU_DEV_CTRL_MRRS_SHFT		12
+#define	FO_PCI_TLU_DEV_CTRL_MPS_MASK		0x00000000000000e0ULL
+#define	FO_PCI_TLU_DEV_CTRL_MPS_SHFT		5
+
+/*
+ * PCI TLU uncorrectable error interrupt enable, interrupt status and
+ * status clear registers
+ */
+#define	FO_PCI_TLU_UERR_INT_S_MASK		0x001fffff00000000ULL
+#define	FO_PCI_TLU_UERR_INT_S_SHFT		32
+#define	FO_PCI_TLU_UERR_INT_UR_S		0x0010000000000000ULL
+#define	OBERON_PCI_TLU_UERR_INT_ECRC_S		0x0008000000000000ULL
+#define	FO_PCI_TLU_UERR_INT_MFP_S		0x0004000000000000ULL
+#define	FO_PCI_TLU_UERR_INT_ROF_S		0x0002000000000000ULL
+#define	FO_PCI_TLU_UERR_INT_UC_S		0x0001000000000000ULL
+#define	FO_PCI_TLU_UERR_INT_CA_S		0x0000800000000000ULL
+#define	FO_PCI_TLU_UERR_INT_CTO_S		0x0000400000000000ULL
+#define	FO_PCI_TLU_UERR_INT_FCP_S		0x0000200000000000ULL
+#define	FIRE_PCI_TLU_UERR_INT_PP_S		0x0000100000000000ULL
+#define	OBERON_PCI_TLU_UERR_INT_POIS_S		0x0000100000000000ULL
+#define	FO_PCI_TLU_UERR_INT_DLP_S		0x0000001000000000ULL
+#define	FO_PCI_TLU_UERR_INT_TE_S		0x0000000100000000ULL
+#define	FO_PCI_TLU_UERR_INT_P_MASK		0x00000000001fffffULL
+#define	FO_PCI_TLU_UERR_INT_P_SHFT		0
+#define	FO_PCI_TLU_UERR_INT_UR_P		0x0000000000100000ULL
+#define	OBERON_PCI_TLU_UERR_INT_ECRC_P		0x0000000000080000ULL
+#define	FO_PCI_TLU_UERR_INT_MFP_P		0x0000000000040000ULL
+#define	FO_PCI_TLU_UERR_INT_ROF_P		0x0000000000020000ULL
+#define	FO_PCI_TLU_UERR_INT_UC_P		0x0000000000010000ULL
+#define	FO_PCI_TLU_UERR_INT_CA_P		0x0000000000008000ULL
+#define	FO_PCI_TLU_UERR_INT_CTO_P		0x0000000000004000ULL
+#define	FO_PCI_TLU_UERR_INT_FCP_P		0x0000000000002000ULL
+#define	FIRE_PCI_TLU_UERR_INT_PP_P		0x0000000000001000ULL
+#define	OBERON_PCI_TLU_UERR_INT_POIS_P		0x0000000000001000ULL
+#define	FO_PCI_TLU_UERR_INT_DLP_P		0x0000000000000010ULL
+#define	FO_PCI_TLU_UERR_INT_TE_P		0x0000000000000001ULL
+
+/*
+ * PCI TLU correctable error interrupt enable, interrupt status and
+ * status clear registers
+ */
+#define	FO_PCI_TLU_CERR_INT_S_MASK		0x001fffff00000000ULL
+#define	FO_PCI_TLU_CERR_INT_S_SHFT		32
+#define	FO_PCI_TLU_CERR_INT_RTO_S		0x0000100000000000ULL
+#define	FO_PCI_TLU_CERR_INT_RNR_S		0x0000010000000000ULL
+#define	FO_PCI_TLU_CERR_INT_BDP_S		0x0000008000000000ULL
+#define	FO_PCI_TLU_CERR_INT_BTP_S		0x0000004000000000ULL
+#define	FO_PCI_TLU_CERR_INT_RE_S		0x0000000100000000ULL
+#define	FO_PCI_TLU_CERR_INT_P_MASK		0x00000000001fffffULL
+#define	FO_PCI_TLU_CERR_INT_P_SHFT		0
+#define	FO_PCI_TLU_CERR_INT_RTO_P		0x0000000000001000ULL
+#define	FO_PCI_TLU_CERR_INT_RNR_P		0x0000000000000100ULL
+#define	FO_PCI_TLU_CERR_INT_BDP_P		0x0000000000000080ULL
+#define	FO_PCI_TLU_CERR_INT_BTP_P		0x0000000000000040ULL
+#define	FO_PCI_TLU_CERR_INT_RE_P		0x0000000000000001ULL
+
+/* PCI TLU reset register */
+#define	FO_PCI_LPU_RST_WE			0x0000000080000000ULL
+#define	FO_PCI_LPU_RST_UNUSED_MASK		0x0000000000000e00ULL
+#define	FO_PCI_LPU_RST_UNUSED_SHFT		9
+#define	FO_PCI_LPU_RST_ERR			0x0000000000000100ULL
+#define	FO_PCI_LPU_RST_TXLINK			0x0000000000000080ULL
+#define	FO_PCI_LPU_RST_RXLINK			0x0000000000000040ULL
+#define	FO_PCI_LPU_RST_SMLINK			0x0000000000000020ULL
+#define	FO_PCI_LPU_RST_LTSSM			0x0000000000000010ULL
+#define	FO_PCI_LPU_RST_TXPHY			0x0000000000000008ULL
+#define	FO_PCI_LPU_RST_RXPHY			0x0000000000000004ULL
+#define	FO_PCI_LPU_RST_TXPCS			0x0000000000000002ULL
+#define	FO_PCI_LPU_RST_RXPCS			0x0000000000000001ULL
+
+/* PCI TLU link control register */
+#define	FO_PCI_TLU_LNK_CTRL_EXTSYNC		0x0000000000000080ULL
+#define	FO_PCI_TLU_LNK_CTRL_CLK			0x0000000000000040ULL
+#define	FO_PCI_TLU_LNK_CTRL_RETRAIN		0x0000000000000020ULL
+#define	FO_PCI_TLU_LNK_CTRL_DIS			0x0000000000000010ULL
+#define	FO_PCI_TLU_LNK_CTRL_RCB			0x0000000000000008ULL
+#define	FO_PCI_TLU_LNK_CTRL_ASPM_L0S_L1S	0x0000000000000003ULL
+#define	FO_PCI_TLU_LNK_CTRL_ASPM_L1S		0x0000000000000002ULL
+#define	FO_PCI_TLU_LNK_CTRL_ASPM_L0S		0x0000000000000001ULL
+#define	FO_PCI_TLU_LNK_CTRL_ASPM_DIS		0x0000000000000000ULL
+
+/* PCI TLU link status register */
+#define	FO_PCI_TLU_LNK_STAT_CLK			0x0000000000001000ULL
+#define	FO_PCI_TLU_LNK_STAT_TRAIN		0x0000000000000800ULL
+#define	FO_PCI_TLU_LNK_STAT_ERR			0x0000000000000400ULL
+#define	FO_PCI_TLU_LNK_STAT_WDTH_MASK		0x00000000000003f0ULL
+#define	FO_PCI_TLU_LNK_STAT_WDTH_SHFT		4
+#define	FO_PCI_TLU_LNK_STAT_SPEED_MASK		0x000000000000000fULL
+#define	FO_PCI_TLU_LNK_STAT_SPEED_SHFT		0
+
+/*
+ * PCI receive/transmit DLU/TLU uncorrectable error header 1/2 log
+ * registers
+ */
+#define	FO_PCI_TLU_UERR_HDR_LOG_MASK		0xffffffffffffffffULL
+#define	FO_PCI_TLU_UERR_HDR_LOG_SHFT		0
+
+/* PCI DLU/LPU interrupt status and mask registers */
+#define	FO_PCI_LPU_INT_INT			0x0000000080000000ULL
+#define	FIRE_PCI_LPU_INT_PRF_CNT2_OFLW		0x0000000000000080ULL
+#define	FIRE_PCI_LPU_INT_PRF_CNT1_OFLW		0x0000000000000040ULL
+#define	FO_PCI_LPU_INT_LNK_LYR			0x0000000000000020ULL
+#define	FO_PCI_LPU_INT_PHY_ERR			0x0000000000000010ULL
+#define	FIRE_PCI_LPU_INT_LTSSM			0x0000000000000008ULL
+#define	FIRE_PCI_LPU_INT_PHY_TX			0x0000000000000004ULL
+#define	FIRE_PCI_LPU_INT_PHY_RX			0x0000000000000002ULL
+#define	FIRE_PCI_LPU_INT_PHY_GB			0x0000000000000001ULL
+
+/* PCI DLU/LPU link layer config register */
+#define	FIRE_PCI_LPU_LNK_LYR_CFG_AUTO_UPDT_DIS	0x0000000000080000ULL
+#define	FIRE_PCI_LPU_LNK_LYR_CFG_FREQ_NAK_EN	0x0000000000040000ULL
+#define	FIRE_PCI_LPU_LNK_LYR_CFG_RPLY_AFTER_REQ	0x0000000000020000ULL
+#define	FIRE_PCI_LPU_LNK_LYR_CFG_LAT_THRS_WR_EN	0x0000000000010000ULL
+#define	FO_PCI_LPU_LNK_LYR_CFG_VC0_EN		0x0000000000000100ULL
+#define	FIRE_PCI_LPU_LNK_LYR_CFG_L0S_ADJ_FAC_EN	0x0000000000000010ULL
+#define	FIER_PCI_LPU_LNK_LYR_CFG_TLP_XMIT_FC_EN	0x0000000000000008ULL
+#define	FO_PCI_LPU_LNK_LYR_CFG_FREQ_ACK_EN	0x0000000000000004ULL
+#define	FO_PCI_LPU_LNK_LYR_CFG_RETRY_DIS	0x0000000000000002ULL
+
+/* PCI DLU/LPU link layer interrupt and status register */
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_LNK_ERR_ACT	0x0000000080000000ULL
+#define	OBERON_PCI_LPU_LNK_LYR_INT_STAT_PBUS_PE 0x0000000000800000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_USPRTD_DLLP	0x0000000000400000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_DLLP_RX_ERR	0x0000000000200000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_BAD_DLLP	0x0000000000100000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_TLP_RX_ERR	0x0000000000040000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_SRC_ERR_TLP	0x0000000000020000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_BAD_TLP	0x0000000000010000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_RBF_UDF_ERR	0x0000000000000200ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_RBF_OVF_ERR	0x0000000000000100ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_EG_TLPM_ERR	0x0000000000000080ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_EG_TFRM_ERR	0x0000000000000040ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_RBF_PE	0x0000000000000020ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_EGRESS_PE	0x0000000000000010ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_RPLY_TMR_TO	0x0000000000000004ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_RPLY_NUM_RO	0x0000000000000002ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_DLNK_PES	0x0000000000000001ULL
+
+/* PCI DLU/LPU flow control update control register */
+#define	FO_PCI_LPU_FLW_CTRL_UPDT_CTRL_FC0_C_EN	0x0000000000000004ULL
+#define	FO_PCI_LPU_FLW_CTRL_UPDT_CTRL_FC0_NP_EN	0x0000000000000002ULL
+#define	FO_PCI_LPU_FLW_CTRL_UPDT_CTRL_FC0_P_EN	0x0000000000000001ULL
+
+/* PCI DLU/LPU txlink ACKNAK latency timer threshold register */
+#define	FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS_MASK	0x000000000000ffffULL
+#define	FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS_SHFT	0
+
+/* PCI DLU/LPU txlink replay timer threshold register */
+#define	FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_MASK	0x00000000000fffffULL
+#define	FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_SHFT	0
+
+/* PCI DLU/LPU txlink FIFO pointer register */
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_MASK	0x00000000ffff0000ULL
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_SHFT	16
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_MASK	0x000000000000ffffULL
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_SHFT	0
+
+/* PCI DLU/LPU phy layer interrupt and status register */
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_PHY_LYR_ERR	0x0000000080000000ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_KC_DLLP_ERR	0x0000000000000800ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_END_POS_ERR	0x0000000000000400ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_LNK_ERR	0x0000000000000200ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_TRN_ERR	0x0000000000000100ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_EDB_DET	0x0000000000000080ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_SDP_END	0x0000000000000040ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_STP_END_EDB	0x0000000000000020ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_INVC_ERR	0x0000000000000010ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_MULTI_SDP	0x0000000000000008ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_MULTI_STP	0x0000000000000004ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_ILL_SDP_POS	0x0000000000000002ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_ILL_STP_POS	0x0000000000000001ULL
+
+/* PCI DLU/LPU LTSSM config2 register */
+#define	FO_PCI_LPU_LTSSM_CFG2_12_TO_MASK	0x00000000ffffffffULL
+#define	FO_PCI_LPU_LTSSM_CFG2_12_TO_SHFT	0
+
+/* PCI DLU/LPU LTSSM config3 register */
+#define	FO_PCI_LPU_LTSSM_CFG3_2_TO_MASK		0x00000000ffffffffULL
+#define	FO_PCI_LPU_LTSSM_CFG3_2_TO_SHFT		0
+
+/* PCI DLU/LPU LTSSM config4 register */
+#define	FO_PCI_LPU_LTSSM_CFG4_TRN_CTRL_MASK	0x00000000ff000000ULL
+#define	FO_PCI_LPU_LTSSM_CFG4_TRN_CTRL_SHFT	24
+#define	FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_MASK	0x0000000000ff0000ULL
+#define	FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_SHFT	16
+#define	FO_PCI_LPU_LTSSM_CFG4_N_FTS_MASK	0x000000000000ff00ULL
+#define	FO_PCI_LPU_LTSSM_CFG4_N_FTS_SHFT	8
+#define	FO_PCI_LPU_LTSSM_CFG4_LNK_NUM_MASK	0x00000000000000ffULL
+#define	FO_PCI_LPU_LTSSM_CFG4_LNK_NUM_SHFT	0
+
+/* PCI DLU/LPU LTSSM config5 register */
+#define	FO_PCI_LPU_LTSSM_CFG5_UNUSED0_MASK	0x00000000ffffe000ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_UNUSED0_SHFT	13
+#define	FO_PCI_LPU_LTSSM_CFG5_RCV_DET_TST_MODE	0x0000000000001000ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_POLL_CMPLNC_DIS	0x0000000000000800ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_TX_IDLE_TX_FTS	0x0000000000000400ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_RX_FTS_RVR_LK	0x0000000000000200ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_UNUSED1_MASK	0x0000000000000180ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_UNUSED1_SHFT	7
+#define	FO_PCI_LPU_LTSSM_CFG5_LPBK_NTRY_ACTIVE	0x0000000000000040ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_LPBK_NTRY_EXIT	0x0000000000000020ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_LPBK_ACTIVE_EXIT	0x0000000000000010ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_L1_IDLE_RCVRY_LK	0x0000000000000008ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_L0_TRN_CNTRL_RST	0x0000000000000004ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_L0_LPBK		0x0000000000000002ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_UNUSED2		0x0000000000000001ULL
+
+/* Controller configuration and status registers */
+#define	FIRE_JBUS_PAR_CTRL			0x60010
+#define	FO_XBC_ERR_LOG_EN			0x61000
+#define	FO_XBC_INT_EN				0x61008
+#define	FO_XBC_INT_STAT				0x61010
+#define	FO_XBC_ERR_STAT_CLR			0x61018
+#define	FIRE_JBC_FATAL_RST_EN			0x61028
+#define	FIRE_JBCINT_ITRANS_ERR_LOG		0x61040
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2		0x61048
+#define	FIRE_JBCINT_OTRANS_ERR_LOG		0x61040
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2		0x61048
+#define	FIRE_FATAL_ERR_LOG			0x61050
+#define	FIRE_FATAL_ERR_LOG2			0x61058
+#define	FIRE_MERGE_TRANS_ERR_LOG		0x61060
+#define	FIRE_DMCINT_ODCD_ERR_LOG		0x61068
+#define	FIRE_DMCINT_IDC_ERR_LOG			0x61070
+#define	FIRE_JBC_CSR_ERR_LOG			0x61078
+#define	FIRE_JBC_CORE_BLOCK_INT_EN		0x61800
+#define	FIRE_JBC_CORE_BLOCK_ERR_STAT		0x61808
+#define	FO_XBC_PRF_CNT_SEL			0x62000
+#define	FO_XBC_PRF_CNT0				0x62008
+#define	FO_XBC_PRF_CNT1				0x62010
+
+/* JBus parity control register */
+#define	FIRE_JBUS_PAR_CTRL_P_EN			0x8000000000000000ULL
+#define	FIRE_JBUS_PAR_CTRL_INVRTD_PAR_MASK	0x000000000000003cULL
+#define	FIRE_JBUS_PAR_CTRL_INVRTD_PAR_SHFT	2
+#define	FIRE_JBUS_PAR_CTRL_NEXT_DATA		0x0000000000000002ULL
+#define	FIRE_JBUS_PAR_CTRL_NEXT_ADDR		0x0000000000000001ULL
+
+/* JBC error log enable register - may also apply to UBC */
+#define	FIRE_JBC_ERR_LOG_EN_SPARE_MASK		0x00000000e0000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_SPARE_SHFT		29
+#define	FIRE_JBC_ERR_LOG_EN_PIO_UNMAP_RD	0x0000000010000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_ILL_ACC_RD		0x0000000008000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_EBUS_TO		0x0000000004000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_MB_PEA		0x0000000002000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_MB_PER		0x0000000001000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_MB_PEW		0x0000000000800000ULL
+#define	FIRE_JBC_ERR_LOG_EN_UE_ASYN		0x0000000000400000ULL
+#define	FIRE_JBC_ERR_LOG_EN_CE_ASYN		0x0000000000200000ULL
+#define	FIRE_JBC_ERR_LOG_EN_JTE			0x0000000000100000ULL
+#define	FIRE_JBC_ERR_LOG_EN_JBE			0x0000000000080000ULL
+#define	FIRE_JBC_ERR_LOG_EN_JUE			0x0000000000040000ULL
+#define	FIRE_JBC_ERR_LOG_EN_IJP			0x0000000000020000ULL
+#define	FIRE_JBC_ERR_LOG_EN_ICISE		0x0000000000010000ULL
+#define	FIRE_JBC_ERR_LOG_EN_CPE			0x0000000000008000ULL
+#define	FIRE_JBC_ERR_LOG_EN_APE			0x0000000000004000ULL
+#define	FIRE_JBC_ERR_LOG_EN_WR_DPE		0x0000000000002000ULL
+#define	FIRE_JBC_ERR_LOG_EN_RD_DPE		0x0000000000001000ULL
+#define	FIRE_JBC_ERR_LOG_EN_ILL_BMW		0x0000000000000800ULL
+#define	FIRE_JBC_ERR_LOG_EN_ILL_BMR		0x0000000000000400ULL
+#define	FIRE_JBC_ERR_LOG_EN_BJC			0x0000000000000200ULL
+#define	FIRE_JBC_ERR_LOG_EN_PIO_UNMAP		0x0000000000000100ULL
+#define	FIRE_JBC_ERR_LOG_EN_PIO_DPE		0x0000000000000080ULL
+#define	FIRE_JBC_ERR_LOG_EN_PIO_CPE		0x0000000000000040ULL
+#define	FIRE_JBC_ERR_LOG_EN_ILL_ACC		0x0000000000000020ULL
+#define	FIRE_JBC_ERR_LOG_EN_UNSOL_RD		0x0000000000000010ULL
+#define	FIRE_JBC_ERR_LOG_EN_UNSOL_INT		0x0000000000000008ULL
+#define	FIRE_JBC_ERR_LOG_EN_JTCEEW		0x0000000000000004ULL
+#define	FIRE_JBC_ERR_LOG_EN_JTCEEI		0x0000000000000002ULL
+#define	FIRE_JBC_ERR_LOG_EN_JTCEER		0x0000000000000001ULL
+
+/* JBC interrupt enable, interrupt status and error status clear registers */
+#define	FIRE_JBC_ERR_INT_SPARE_S_MASK		0xe000000000000000ULL
+#define	FIRE_JBC_ERR_INT_SPARE_S_SHFT		61
+#define	FIRE_JBC_ERR_INT_PIO_UNMAP_RD_S		0x1000000000000000ULL
+#define	FIRE_JBC_ERR_INT_ILL_ACC_RD_S		0x0800000000000000ULL
+#define	FIRE_JBC_ERR_INT_EBUS_TO_S		0x0400000000000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PEA_S		0x0200000000000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PER_S		0x0100000000000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PEW_S		0x0080000000000000ULL
+#define	FIRE_JBC_ERR_INT_UE_ASYN_S		0x0040000000000000ULL
+#define	FIRE_JBC_ERR_INT_CE_ASYN_S		0x0020000000000000ULL
+#define	FIRE_JBC_ERR_INT_JTE_S			0x0010000000000000ULL
+#define	FIRE_JBC_ERR_INT_JBE_S			0x0008000000000000ULL
+#define	FIRE_JBC_ERR_INT_JUE_S			0x0004000000000000ULL
+#define	FIRE_JBC_ERR_INT_IJP_S			0x0002000000000000ULL
+#define	FIRE_JBC_ERR_INT_ICISE_S		0x0001000000000000ULL
+#define	FIRE_JBC_ERR_INT_CPE_S			0x0000800000000000ULL
+#define	FIRE_JBC_ERR_INT_APE_S			0x0000400000000000ULL
+#define	FIRE_JBC_ERR_INT_WR_DPE_S		0x0000200000000000ULL
+#define	FIRE_JBC_ERR_INT_RD_DPE_S		0x0000100000000000ULL
+#define	FIRE_JBC_ERR_INT_ILL_BMW_S		0x0000080000000000ULL
+#define	FIRE_JBC_ERR_INT_ILL_BMR_S		0x0000040000000000ULL
+#define	FIRE_JBC_ERR_INT_BJC_S			0x0000020000000000ULL
+#define	FIRE_JBC_ERR_INT_PIO_UNMAP_S		0x0000010000000000ULL
+#define	FIRE_JBC_ERR_INT_PIO_DPE_S		0x0000008000000000ULL
+#define	FIRE_JBC_ERR_INT_PIO_CPE_S		0x0000004000000000ULL
+#define	FIRE_JBC_ERR_INT_ILL_ACC_S		0x0000002000000000ULL
+#define	FIRE_JBC_ERR_INT_UNSOL_RD_S		0x0000001000000000ULL
+#define	FIRE_JBC_ERR_INT_UNSOL_INT_S		0x0000000800000000ULL
+#define	FIRE_JBC_ERR_INT_JTCEEW_S		0x0000000400000000ULL
+#define	FIRE_JBC_ERR_INT_JTCEEI_S		0x0000000200000000ULL
+#define	FIRE_JBC_ERR_INT_JTCEER_S		0x0000000100000000ULL
+#define	FIRE_JBC_ERR_INT_SPARE_P_MASK		0x00000000e0000000ULL
+#define	FIRE_JBC_ERR_INT_SPARE_P_SHFT		29
+#define	FIRE_JBC_ERR_INT_PIO_UNMAP_RD_P		0x0000000010000000ULL
+#define	FIRE_JBC_ERR_INT_ILL_ACC_RD_P		0x0000000008000000ULL
+#define	FIRE_JBC_ERR_INT_EBUS_TO_P		0x0000000004000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PEA_P		0x0000000002000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PER_P		0x0000000001000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PEW_P		0x0000000000800000ULL
+#define	FIRE_JBC_ERR_INT_UE_ASYN_P		0x0000000000400000ULL
+#define	FIRE_JBC_ERR_INT_CE_ASYN_P		0x0000000000200000ULL
+#define	FIRE_JBC_ERR_INT_JTE_P			0x0000000000100000ULL
+#define	FIRE_JBC_ERR_INT_JBE_P			0x0000000000080000ULL
+#define	FIRE_JBC_ERR_INT_JUE_P			0x0000000000040000ULL
+#define	FIRE_JBC_ERR_INT_IJP_P			0x0000000000020000ULL
+#define	FIRE_JBC_ERR_INT_ICISE_P		0x0000000000010000ULL
+#define	FIRE_JBC_ERR_INT_CPE_P			0x0000000000008000ULL
+#define	FIRE_JBC_ERR_INT_APE_P			0x0000000000004000ULL
+#define	FIRE_JBC_ERR_INT_WR_DPE_P		0x0000000000002000ULL
+#define	FIRE_JBC_ERR_INT_RD_DPE_P		0x0000000000001000ULL
+#define	FIRE_JBC_ERR_INT_ILL_BMW_P		0x0000000000000800ULL
+#define	FIRE_JBC_ERR_INT_ILL_BMR_P		0x0000000000000400ULL
+#define	FIRE_JBC_ERR_INT_BJC_P			0x0000000000000200ULL
+#define	FIRE_JBC_ERR_INT_PIO_UNMAP_P		0x0000000000000100ULL
+#define	FIRE_JBC_ERR_INT_PIO_DPE_P		0x0000000000000080ULL
+#define	FIRE_JBC_ERR_INT_PIO_CPE_P		0x0000000000000040ULL
+#define	FIRE_JBC_ERR_INT_ILL_ACC_P		0x0000000000000020ULL
+#define	FIRE_JBC_ERR_INT_UNSOL_RD_P		0x0000000000000010ULL
+#define	FIRE_JBC_ERR_INT_UNSOL_INT_P		0x0000000000000008ULL
+#define	FIRE_JBC_ERR_INT_JTCEEW_P		0x0000000000000004ULL
+#define	FIRE_JBC_ERR_INT_JTCEEI_P		0x0000000000000002ULL
+#define	FIRE_JBC_ERR_INT_JTCEER_P		0x0000000000000001ULL
+
+/* UBC interrupt enable, error status and error status clear registers */
+#define	OBERON_UBC_ERR_INT_PIORBEUE_S		0x0004000000000000ULL
+#define	OBERON_UBC_ERR_INT_PIOWBEUE_S		0x0002000000000000ULL
+#define	OBERON_UBC_ERR_INT_PIOWTUE_S		0x0001000000000000ULL
+#define	OBERON_UBC_ERR_INT_MEMWTAXB_S		0x0000080000000000ULL
+#define	OBERON_UBC_ERR_INT_MEMRDAXB_S		0x0000040000000000ULL
+#define	OBERON_UBC_ERR_INT_DMAWTUEB_S		0x0000020000000000ULL
+#define	OBERON_UBC_ERR_INT_DMARDUEB_S		0x0000010000000000ULL
+#define	OBERON_UBC_ERR_INT_MEMWTAXA_S		0x0000000800000000ULL
+#define	OBERON_UBC_ERR_INT_MEMRDAXA_S		0x0000000400000000ULL
+#define	OBERON_UBC_ERR_INT_DMAWTUEA_S		0x0000000200000000ULL
+#define	OBERON_UBC_ERR_INT_DMARDUEA_S		0x0000000100000000ULL
+#define	OBERON_UBC_ERR_INT_PIORBEUE_P		0x0000000000040000ULL
+#define	OBERON_UBC_ERR_INT_PIOWBEUE_P		0x0000000000020000ULL
+#define	OBERON_UBC_ERR_INT_PIOWTUE_P		0x0000000000010000ULL
+#define	OBERON_UBC_ERR_INT_MEMWTAXB_P		0x0000000000000800ULL
+#define	OBERON_UBC_ERR_INT_MEMRDAXB_P		0x0000000000000400ULL
+#define	OBERON_UBC_ERR_INT_DMARDUEB_P		0x0000000000000200ULL
+#define	OBERON_UBC_ERR_INT_DMAWTUEB_P		0x0000000000000100ULL
+#define	OBERON_UBC_ERR_INT_MEMWTAXA_P		0x0000000000000008ULL
+#define	OBERON_UBC_ERR_INT_MEMRDAXA_P		0x0000000000000004ULL
+#define	OBERON_UBC_ERR_INT_DMAWTUEA_P		0x0000000000000002ULL
+#define	OBERON_UBC_ERR_INT_DMARDUEA_P		0x0000000000000001ULL
+
+/* JBC fatal reset enable register */
+#define	FIRE_JBC_FATAL_RST_EN_SPARE_P_INT_MASK	0x000000000c000000ULL
+#define	FIRE_JBC_FATAL_RST_EN_SPARE_P_INT_SHFT	26
+#define	FIRE_JBC_FATAL_RST_EN_MB_PEA_P_INT	0x0000000002000000ULL
+#define	FIRE_JBC_FATAL_RST_EN_CPE_P_INT		0x0000000000008000ULL
+#define	FIRE_JBC_FATAL_RST_EN_APE_P_INT		0x0000000000004000ULL
+#define	FIRE_JBC_FATAL_RST_EN_PIO_CPE_INT	0x0000000000000040ULL
+#define	FIRE_JBC_FATAL_RST_EN_JTCEEW_P_INT	0x0000000000000004ULL
+#define	FIRE_JBC_FATAL_RST_EN_JTCEEI_P_INT	0x0000000000000002ULL
+#define	FIRE_JBC_FATAL_RST_EN_JTCEER_P_INT	0x0000000000000001ULL
+
+/* JBC JBCINT in transaction error log register */
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_Q_WORD_MASK	0x00c0000000000000ULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_Q_WORD_SHFT	54
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_TRANSID_MASK	0x0003000000000000ULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_TRANSID_SHFT	48
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_ADDR_MASK	0x000007ffffffffffULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_ADDR_SHFT	0
+
+/* JBC JBCINT in transaction error log register 2 */
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_ARB_WN_MASK	0x000ffffff0000000ULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_ARB_WN_SHFT	28
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_J_REQ_MASK	0x000000000fe00000ULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_J_REQ_SHFT	21
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_J_PACK_MASK	0x00000000001fffffULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_J_PACK_SHFT	0
+
+/* JBC JBCINT out transaction error log register */
+#define	FIRE_JBCINT_OTRANS_ERR_LOG_TRANSID_MASK	0x003f000000000000ULL
+#define	FIRE_JBCINT_OTRANS_ERR_LOG_TRANSID_SHFT	48
+#define	FIRE_JBCINT_OTRANS_ERR_LOG_ADDR_MASK	0x000007ffffffffffULL
+#define	FIRE_JBCINT_OTRANS_ERR_LOG_ADDR_SHFT	0
+
+/* JBC JBCINT out transaction error log register 2 */
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_ARB_WN_MASK	0x000ffffff0000000ULL
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_ARB_WN_SHFT	28
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_J_REQ_MASK	0x000000000fe00000ULL
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_J_REQ_SHFT	21
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_J_PACK_MASK	0x00000000001fffffULL
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_J_PACK_SHFT	0
+
+/* JBC merge transaction error log register */
+#define	FIRE_FATAL_ERR_LOG_DATA_MASK		0xffffffffffffffffULL
+#define	FIRE_FATAL_ERR_LOG_DATA_SHFT		0
+
+/* JBC merge transaction error log register 2 */
+#define	FIRE_FATAL_ERR_LOG2_ARB_WN_MASK		0x000ffffff0000000ULL
+#define	FIRE_FATAL_ERR_LOG2_ARB_WN_SHFT		28
+#define	FIRE_FATAL_ERR_LOG2_J_REQ_MASK		0x000000000fe00000ULL
+#define	FIRE_FATAL_ERR_LOG2_J_REQ_SHFT		21
+#define	FIRE_FATAL_ERR_LOG2_J_PACK_MASK		0x00000000001fffffULL
+#define	FIRE_FATAL_ERR_LOG2_J_PACK_SHFT		0
+
+/* JBC merge transaction error log register */
+#define	FIRE_MERGE_TRANS_ERR_LOG_Q_WORD_MASK	0x00c0000000000000ULL
+#define	FIRE_MERGE_TRANS_ERR_LOG_Q_WORD_SHFT	54
+#define	FIRE_MERGE_TRANS_ERR_LOG_TRANSID_MASK	0x0003000000000000ULL
+#define	FIRE_MERGE_TRANS_ERR_LOG_TRANSID_SHFT	48
+#define	FIRE_MERGE_TRANS_ERR_LOG_JBC_TAG_MASK	0x0000f80000000000ULL
+#define	FIRE_MERGE_TRANS_ERR_LOG_JBC_TAG_SHFT	43
+#define	FIRE_MERGE_TRANS_ERR_LOG_ADDR_MASK	0x000007ffffffffffULL
+#define	FIRE_MERGE_TRANS_ERR_LOG_ADDR_SHFT	0
+
+/* JBC DMCINT ODCD error log register */
+#define	FIRE_DMCINT_ODCD_ERR_LOG_TRANS_ID_MASK	0x0030000000000000ULL
+#define	FIRE_DMCINT_ODCD_ERR_LOG_TRANS_ID_SHFT	52
+#define	FIRE_DMCINT_ODCD_ERR_LOG_AID_MASK	0x000f000000000000ULL
+#define	FIRE_DMCINT_ODCD_ERR_LOG_AID_SHFT	48
+#define	FIRE_DMCINT_ODCD_ERR_LOG_TTYPE_MASK	0x0000f80000000000ULL
+#define	FIRE_DMCINT_ODCD_ERR_LOG_TTYPE_SHFT	43
+#define	FIRE_DMCINT_ODCD_ERR_LOG_ADDR_MASK	0x000007ffffffffffULL
+#define	FIRE_DMCINT_ODCD_ERR_LOG_ADDR_SHFT	0
+
+/* JBC DMCINT IDC error log register */
+#define	FIRE_DMCINT_IDC_ERR_DMC_CTAG_MASK	0x000000000fff0000ULL
+#define	FIRE_DMCINT_IDC_ERR_DMC_CTAG_SHFT	16
+#define	FIRE_DMCINT_IDC_ERR_TRANSID_MASK	0x000000000000c000ULL
+#define	FIRE_DMCINT_IDC_ERR_AGNTID_MASK		0x0000000000003c00ULL
+#define	FIRE_DMCINT_IDC_ERR_AGNTID_SHFT		10
+#define	FIRE_DMCINT_IDC_ERR_SRCID_MASK		0x00000000000003e0ULL
+#define	FIRE_DMCINT_IDC_ERR_SRCID_SHFT		5
+#define	FIRE_DMCINT_IDC_ERR_TARGID_MASK		0x000000000000001fULL
+#define	FIRE_DMCINT_IDC_ERRO_TARGID_SHFT	0
+
+/* JBC CSR error log register */
+#define	FIRE_JBC_CSR_ERR_LOG_WR			0x0000040000000000ULL
+#define	FIRE_JBC_CSR_ERR_LOG_BMASK_MASK		0x000003fffc000000ULL
+#define	FIRE_JBC_CSR_ERR_LOG_BMASK_SHFT		26
+#define	FIRE_JBC_CSR_ERR_LOG_ADDR_MASK		0x0000000003ffffffULL
+#define	FIRE_JBC_CSR_ERR_LOG_ADDR_SHFT		0
+
+/* JBC core and block interrupt enable register */
+#define	FIRE_JBC_CORE_BLOCK_INT_EN_JBC		0x8000000000000000ULL
+#define	FIRE_JBC_CORE_BLOCK_INT_EN_CSR		0x0000000000000008ULL
+#define	FIRE_JBC_CORE_BLOCK_INT_EN_MERGE	0x0000000000000004ULL
+#define	FIRE_JBC_CORE_BLOCK_INT_EN_JBCINT	0x0000000000000002ULL
+#define	FIRE_JBC_CORE_BLOCK_INT_EN_DMCINT	0x0000000000000001ULL
+
+/* JBC core and block error status register */
+#define	FIRE_JBC_CORE_BLOCK_ERR_STAT_CSR	0x0000000000000008ULL
+#define	FIRE_JBC_CORE_BLOCK_ERR_STAT_MERGE	0x0000000000000004ULL
+#define	FIRE_JBC_CORE_BLOCK_ERR_STAT_JBCINT	0x0000000000000002ULL
+#define	FIRE_JBC_CORE_BLOCK_ERR_STAT_DMCINT	0x0000000000000001ULL
+
+/* JBC performance counter select register - may also apply to UBC */
+#define	FO_XBC_PRF_CNT_PIO_RD_PCIEB		0x0000000000000018ULL
+#define	FO_XBC_PRF_CNT_PIO_WR_PCIEB		0x0000000000000017ULL
+#define	FO_XBC_PRF_CNT_PIO_RD_PCIEA		0x0000000000000016ULL
+#define	FO_XBC_PRF_CNT_PIO_WR_PCIEA		0x0000000000000015ULL
+#define	FO_XBC_PRF_CNT_WB			0x0000000000000014ULL
+#define	FO_XBC_PRF_CNT_PIO_FRGN			0x0000000000000013ULL
+#define	FO_XBC_PRF_CNT_XB_NCHRNT		0x0000000000000012ULL
+#define	FO_XBC_PRF_CNT_FO_CHRNT			0x0000000000000011ULL
+#define	FO_XBC_PRF_CNT_XB_CHRNT			0x0000000000000010ULL
+#define	FO_XBC_PRF_CNT_AOKOFF_DOKOFF		0x000000000000000fULL
+#define	FO_XBC_PRF_CNT_DOKOFF			0x000000000000000eULL
+#define	FO_XBC_PRF_CNT_AOKOFF			0x000000000000000dULL
+#define	FO_XBC_PRF_CNT_RD_TOTAL			0x000000000000000cULL
+#define	FO_XBC_PRF_CNT_WR_TOTAL			0x000000000000000bULL
+#define	FO_XBC_PRF_CNT_WR_PARTIAL		0x000000000000000aULL
+#define	FO_XBC_PRF_CNT_PIOS_CSR_RINGB		0x0000000000000009ULL
+#define	FO_XBC_PRF_CNT_PIOS_CSR_RINGA		0x0000000000000008ULL
+#define	FO_XBC_PRF_CNT_PIOS_EBUS		0x0000000000000007ULL
+#define	FO_XBC_PRF_CNT_PIOS_I2C			0x0000000000000006ULL
+#define	FO_XBC_PRF_CNT_RD_LAT_SMPLS		0x0000000000000005ULL
+#define	FO_XBC_PRF_CNT_RD_LAT			0x0000000000000004ULL
+#define	FO_XBC_PRF_CNT_ON_XB			0x0000000000000003ULL
+#define	FO_XBC_PRF_CNT_XB_IDL			0x0000000000000002ULL
+#define	FO_XBC_PRF_CNT_XB_CLK			0x0000000000000001ULL
+#define	FO_XBC_PRF_CNT_NONE			0x0000000000000000ULL
+#define	FO_XBC_PRF_CNT_CNT1_SHFT		8
+#define	FO_XBC_PRF_CNT_CNT0_SHFT		0
+
+/* JBC performance counter 0/1 registers - may also apply to UBC */
+#define	FO_XBC_PRF_CNT_MASK			0xffffffffffffffffULL
+#define	FO_XBC_PRF_CNT_SHFT			0
+
+/* Lookup tables */
+const uint16_t fire_freq_nak_tmr_thrs[6][4] = {
+	{ 0x00ed, 0x049, 0x043, 0x030 },
+	{ 0x01a0, 0x076, 0x06b, 0x048 },
+	{ 0x022f, 0x09a, 0x056, 0x056 },
+	{ 0x042f, 0x11a, 0x096, 0x096 },
+	{ 0x082f, 0x21a, 0x116, 0x116 },
+	{ 0x102f, 0x41a, 0x216, 0x216 }
+};
+
+const uint16_t fire_rply_tmr_thrs[6][4] = {
+	{ 0x0379, 0x112, 0x0fc, 0x0b4 },
+	{ 0x0618, 0x1BA, 0x192, 0x10e },
+	{ 0x0831, 0x242, 0x143, 0x143 },
+	{ 0x0fb1, 0x422, 0x233, 0x233 },
+	{ 0x1eb0, 0x7e1, 0x412, 0x412 },
+	{ 0x3cb0, 0xf61, 0x7d2, 0x7d2 }
+};
+
+/* Register default values */
+#define	FO_PCI_TLU_CTRL_L0S_TIM_DFLT		0xda
+#define	FO_PCI_TLU_CTRL_CFG_DFLT		0x1
+#define	FO_PCI_LPU_LTSSM_CFG2_12_TO_DFLT	0x2dc6c0
+#define	FO_PCI_LPU_LTSSM_CFG3_2_TO_DFLT		0x7a120
+#define	FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_DFLT	0x2
+#define	FO_PCI_LPU_LTSSM_CFG4_N_FTS_DFLT	0x8c
+#define	OBERON_PCI_LPU_TXLNK_RPLY_TMR_THRS_DFLT	0xc9
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_DFLT	0x0
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_DFLT	0xffff
+
+/* INO macros */
+#define	FO_EQ_FIRST_INO				0x18
+#define	FO_EQ_LAST_INO				0x3b
+#define	FO_DMC_PEC_INO				0x3e
+#define	FO_XCB_INO				0x3f
+#define	FO_MAX_INO				FO_XCB_INO
+
+/* Device space macros */
+#define	FO_CONF_BUS_SHFT			20
+#define	FO_CONF_DEV_SHFT			15
+#define	FO_CONF_FUNC_SHFT			12
+#define	FO_CONF_REG_SHFT			0
+#define	FO_IO_SIZE				0x10000000
+#define	FO_MEM_SIZE				0x1ffff0000
+
+#define	FO_CONF_OFF(bus, slot, func, reg)				\
+	(((bus) << FO_CONF_BUS_SHFT) |					\
+	((slot) << FO_CONF_DEV_SHFT) |					\
+	((func) << FO_CONF_FUNC_SHFT) |					\
+	((reg) << FO_CONF_REG_SHFT))
+
+/* Width of the physical addresses the IOMMU translates to */
+#define	FIRE_IOMMU_BITS				43
+#define	OBERON_IOMMU_BITS			47
+
+/* Event queue macros */
+#define	FO_EQ_ALIGNMENT				(512 * 1024)
+#define	FO_EQ_NRECORDS				128
+#define	FO_EQ_RECORD_SIZE			64
+
+/* Event queue record format */
+struct fo_msiq_record {
+	uint64_t	fomqr_word0;
+	uint64_t	fomqr_word1;
+	uint64_t	fomqr_reserved[6];
+};
+
+#define	FO_MQR_WORD0_FMT_TYPE_MASK		0x7f00000000000000ULL
+#define	FO_MQR_WORD0_FMT_TYPE_SHFT		56
+#define	FO_MQR_WORD0_FMT_TYPE_MSI64		0x7800000000000000ULL
+#define	FO_MQR_WORD0_FMT_TYPE_MSI32		0x5800000000000000ULL
+#define	FO_MQR_WORD0_FMT_TYPE_MSG		0x3000000000000000ULL
+#define	FO_MQR_WORD0_FMT_TYPE_MSG_ROUTE_MASK	0x0700000000000000ULL
+#define	FO_MQR_WORD0_FMT_TYPE_MSG_ROUTE_SHFT	56
+#define	FO_MQR_WORD0_LENGTH_MASK		0x00ffc00000000000ULL
+#define	FO_MQR_WORD0_LENGTH_SHFT		46
+#define	FO_MQR_WORD0_ADDR0_MASK			0x00003fff00000000ULL
+#define	FO_MQR_WORD0_ADDR0_SHFT			32
+#define	FO_MQR_WORD0_RID_MASK			0x00000000ffff0000ULL
+#define	FO_MQR_WORD0_RID_SHFT			16
+#define	FO_MQR_WORD0_DATA0_MASK			0x000000000000ffffULL
+#define	FO_MQR_WORD0_DATA0_SHFT			0
+#define	FO_MQR_WORD1_ADDR1_MASK			0xffffffffffff0000ULL
+#define	FO_MQR_WORD1_ADDR1_SHFT			16
+#define	FO_MQR_WORD1_DATA1_MASK			0x000000000000ffffULL
+#define	FO_MQR_WORD1_DATA1_SHFT			0
+
+#endif /* !_SPARC64_PCI_FIREREG_H_ */


Property changes on: trunk/sys/sparc64/pci/firereg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/firevar.h
===================================================================
--- trunk/sys/sparc64/pci/firevar.h	                        (rev 0)
+++ trunk/sys/sparc64/pci/firevar.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,90 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 by Marius Strobl <marius at 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, this list of conditions, and the following disclaimer,
+ *    without modification, immediately at the beginning of the file.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/pci/firevar.h 292789 2015-12-27 19:37:47Z marius $
+ */
+
+#ifndef _SPARC64_PCI_FIREVAR_H_
+#define	_SPARC64_PCI_FIREVAR_H_
+
+struct fire_softc {
+	/*
+	 * This is here so that we can hook up the common bus interface
+	 * methods in ofw_pci.c directly.
+	 */
+	struct ofw_pci_softc		sc_ops;
+
+	struct iommu_state		sc_is;
+	struct bus_dma_methods		sc_dma_methods;
+
+	struct mtx			sc_msi_mtx;
+	struct mtx			sc_pcib_mtx;
+
+	struct resource			*sc_mem_res[FIRE_NREG];
+	struct resource			*sc_irq_res[FIRE_NINTR];
+	void				*sc_ihand[FIRE_NINTR];
+
+	device_t			sc_dev;
+
+	uint64_t			*sc_msiq;
+	u_char				*sc_msi_bitmap;
+	uint32_t			*sc_msi_msiq_table;
+	u_char				*sc_msiq_bitmap;
+	uint64_t			sc_msi_addr32;
+	uint64_t			sc_msi_addr64;
+	uint32_t			sc_msi_count;
+	uint32_t			sc_msi_first;
+	uint32_t			sc_msi_data_mask;
+	uint32_t			sc_msix_data_width;
+	uint32_t			sc_msiq_count;
+	uint32_t			sc_msiq_size;
+	uint32_t			sc_msiq_first;
+	uint32_t			sc_msiq_ino_first;
+
+	u_int				sc_mode;
+#define	FIRE_MODE_FIRE			0
+#define	FIRE_MODE_OBERON		1
+
+	u_int				sc_flags;
+#define	FIRE_MSIX			(1 << 0)
+
+	uint32_t			sc_ign;
+
+	uint32_t			sc_stats_ilu_err;
+	uint32_t			sc_stats_jbc_ce_async;
+	uint32_t			sc_stats_jbc_unsol_int;
+	uint32_t			sc_stats_jbc_unsol_rd;
+	uint32_t			sc_stats_mmu_err;
+	uint32_t			sc_stats_tlu_ce;
+	uint32_t			sc_stats_tlu_oe_non_fatal;
+	uint32_t			sc_stats_tlu_oe_rx_err;
+	uint32_t			sc_stats_tlu_oe_tx_err;
+	uint32_t			sc_stats_ubc_dmardue;
+};
+
+#endif /* !_SPARC64_PCI_FIREVAR_H_ */


Property changes on: trunk/sys/sparc64/pci/firevar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/ofw_pci.c
===================================================================
--- trunk/sys/sparc64/pci/ofw_pci.c	                        (rev 0)
+++ trunk/sys/sparc64/pci/ofw_pci.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,413 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm at FreeBSD.org>
+ * Copyright (c) 2005 - 2015 by Marius Strobl <marius at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: psycho.c,v 1.35 2001/09/10 16:17:06 eeh Exp
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/pci/ofw_pci.c 292789 2015-12-27 19:37:47Z marius $");
+
+#include "opt_ofw_pci.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/openfirm.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <machine/asi.h>
+#include <machine/bus.h>
+#include <machine/bus_private.h>
+#include <machine/cpufunc.h>
+#include <machine/fsr.h>
+#include <machine/resource.h>
+
+#include <sparc64/pci/ofw_pci.h>
+
+/* XXX */
+extern struct bus_space_tag nexus_bustag;
+
+int
+ofw_pci_attach_common(device_t dev, bus_dma_tag_t dmat, u_long iosize,
+    u_long memsize)
+{
+	struct ofw_pci_softc *sc;
+	struct ofw_pci_ranges *range;
+	phandle_t node;
+	uint32_t prop_array[2];
+	u_int i, j, nrange;
+
+	sc = device_get_softc(dev);
+	node = ofw_bus_get_node(dev);
+	sc->sc_node = node;
+	sc->sc_pci_dmat = dmat;
+
+	/* Initialize memory and I/O rmans. */
+	sc->sc_pci_io_rman.rm_type = RMAN_ARRAY;
+	sc->sc_pci_io_rman.rm_descr = "PCI I/O Ports";
+	if (rman_init(&sc->sc_pci_io_rman) != 0 ||
+	    rman_manage_region(&sc->sc_pci_io_rman, 0, iosize) != 0) {
+		device_printf(dev, "failed to set up I/O rman\n");
+		return (ENXIO);
+	}
+	sc->sc_pci_mem_rman.rm_type = RMAN_ARRAY;
+	sc->sc_pci_mem_rman.rm_descr = "PCI Memory";
+	if (rman_init(&sc->sc_pci_mem_rman) != 0 ||
+	    rman_manage_region(&sc->sc_pci_mem_rman, 0, memsize) != 0) {
+		device_printf(dev, "failed to set up memory rman\n");
+		return (ENXIO);
+	}
+
+	/*
+	 * Find the addresses of the various bus spaces.  The physical
+	 * start addresses of the ranges are the configuration, I/O and
+	 * memory handles.  There should not be multiple ones of one kind.
+	 */
+	nrange = OF_getprop_alloc(node, "ranges", sizeof(*range),
+	    (void **)&range);
+	for (i = 0; i < nrange; i++) {
+		j = OFW_PCI_RANGE_CS(&range[i]);
+		if (sc->sc_pci_bh[j] != 0) {
+			device_printf(dev, "duplicate range for space %d\n",
+			    j);
+			free(range, M_OFWPROP);
+			return (EINVAL);
+		}
+		sc->sc_pci_bh[j] = OFW_PCI_RANGE_PHYS(&range[i]);
+	}
+	free(range, M_OFWPROP);
+
+	/*
+	 * Make sure that the expected ranges are actually present.
+	 * The OFW_PCI_CS_MEM64 one is not currently used.
+	 */
+	if (sc->sc_pci_bh[OFW_PCI_CS_CONFIG] == 0) {
+		device_printf(dev, "missing CONFIG range\n");
+		return (ENXIO);
+	}
+	if (sc->sc_pci_bh[OFW_PCI_CS_IO] == 0) {
+		device_printf(dev, "missing IO range\n");
+		return (ENXIO);
+	}
+	if (sc->sc_pci_bh[OFW_PCI_CS_MEM32] == 0) {
+		device_printf(dev, "missing MEM32 range\n");
+		return (ENXIO);
+	}
+
+	/* Allocate our tags. */
+	sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, &nexus_bustag,
+	    PCI_IO_BUS_SPACE, NULL);
+	if (sc->sc_pci_iot == NULL) {
+		device_printf(dev, "could not allocate PCI I/O tag\n");
+		return (ENXIO);
+	}
+	sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, &nexus_bustag,
+	    PCI_CONFIG_BUS_SPACE, NULL);
+	if (sc->sc_pci_cfgt == NULL) {
+		device_printf(dev,
+		    "could not allocate PCI configuration space tag\n");
+		return (ENXIO);
+	}
+
+	/*
+	 * Get the bus range from the firmware.
+	 */
+	i = OF_getprop(node, "bus-range", (void *)prop_array,
+	    sizeof(prop_array));
+	if (i == -1) {
+		device_printf(dev, "could not get bus-range\n");
+		return (ENXIO);
+	}
+	if (i != sizeof(prop_array)) {
+		device_printf(dev, "broken bus-range (%d)", i);
+		return (EINVAL);
+	}
+	sc->sc_pci_secbus = prop_array[0];
+	sc->sc_pci_subbus = prop_array[1];
+	if (bootverbose != 0)
+		device_printf(dev, "bus range %u to %u; PCI bus %d\n",
+		    sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus);
+
+	ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t));
+
+	return (0);
+}
+
+uint32_t
+ofw_pci_read_config_common(device_t dev, u_int regmax, u_long offset,
+    u_int bus, u_int slot, u_int func, u_int reg, int width)
+{
+	struct ofw_pci_softc *sc;
+	bus_space_handle_t bh;
+	uint32_t r, wrd;
+	int i;
+	uint16_t shrt;
+	uint8_t byte;
+
+	sc = device_get_softc(dev);
+	if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
+	    slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > regmax)
+		return (-1);
+
+	bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
+	switch (width) {
+	case 1:
+		i = bus_space_peek_1(sc->sc_pci_cfgt, bh, offset, &byte);
+		r = byte;
+		break;
+	case 2:
+		i = bus_space_peek_2(sc->sc_pci_cfgt, bh, offset, &shrt);
+		r = shrt;
+		break;
+	case 4:
+		i = bus_space_peek_4(sc->sc_pci_cfgt, bh, offset, &wrd);
+		r = wrd;
+		break;
+	default:
+		panic("%s: bad width %d", __func__, width);
+		/* NOTREACHED */
+	}
+
+	if (i) {
+#ifdef OFW_PCI_DEBUG
+		printf("%s: read data error reading: %d.%d.%d: 0x%x\n",
+		    __func__, bus, slot, func, reg);
+#endif
+		r = -1;
+	}
+	return (r);
+}
+
+void
+ofw_pci_write_config_common(device_t dev, u_int regmax, u_long offset,
+    u_int bus, u_int slot, u_int func, u_int reg, uint32_t val, int width)
+{
+	struct ofw_pci_softc *sc;
+	bus_space_handle_t bh;
+
+	sc = device_get_softc(dev);
+	if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
+	    slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > regmax)
+		return;
+
+	bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
+	switch (width) {
+	case 1:
+		bus_space_write_1(sc->sc_pci_cfgt, bh, offset, val);
+		break;
+	case 2:
+		bus_space_write_2(sc->sc_pci_cfgt, bh, offset, val);
+		break;
+	case 4:
+		bus_space_write_4(sc->sc_pci_cfgt, bh, offset, val);
+		break;
+	default:
+		panic("%s: bad width %d", __func__, width);
+		/* NOTREACHED */
+	}
+}
+
+ofw_pci_intr_t
+ofw_pci_route_interrupt_common(device_t bridge, device_t dev, int pin)
+{
+	struct ofw_pci_softc *sc;
+	struct ofw_pci_register reg;
+	ofw_pci_intr_t pintr, mintr;
+
+	sc = device_get_softc(bridge);
+	pintr = pin;
+	if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
+	    &reg, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
+	    NULL) != 0)
+		return (mintr);
+	return (PCI_INVALID_IRQ);
+}
+
+void
+ofw_pci_dmamap_sync_stst_order_common(void)
+{
+	static u_char buf[VIS_BLOCKSIZE] __aligned(VIS_BLOCKSIZE);
+	register_t reg, s;
+
+	s = intr_disable();
+	reg = rd(fprs);
+	wr(fprs, reg | FPRS_FEF, 0);
+	__asm __volatile("stda %%f0, [%0] %1"
+	    : : "r" (buf), "n" (ASI_BLK_COMMIT_S));
+	membar(Sync);
+	wr(fprs, reg, 0);
+	intr_restore(s);
+}
+
+int
+ofw_pci_read_ivar(device_t dev, device_t child __unused, int which,
+    uintptr_t *result)
+{
+	struct ofw_pci_softc *sc;
+
+	switch (which) {
+	case PCIB_IVAR_DOMAIN:
+		*result = device_get_unit(dev);
+		return (0);
+	case PCIB_IVAR_BUS:
+		sc = device_get_softc(dev);
+		*result = sc->sc_pci_secbus;
+		return (0);
+	}
+	return (ENOENT);
+}
+
+struct resource *
+ofw_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct ofw_pci_softc *sc;
+	struct resource *rv;
+	struct rman *rm;
+
+	sc = device_get_softc(bus);
+	switch (type) {
+	case SYS_RES_IRQ:
+		/*
+		 * XXX: Don't accept blank ranges for now, only single
+		 * interrupts.  The other case should not happen with
+		 * the MI PCI code ...
+		 * XXX: This may return a resource that is out of the
+		 * range that was specified.  Is this correct ...?
+		 */
+		if (start != end)
+			panic("%s: XXX: interrupt range", __func__);
+		return (bus_generic_alloc_resource(bus, child, type, rid,
+		    start, end, count, flags));
+	case SYS_RES_MEMORY:
+		rm = &sc->sc_pci_mem_rman;
+		break;
+	case SYS_RES_IOPORT:
+		rm = &sc->sc_pci_io_rman;
+		break;
+	default:
+		return (NULL);
+	}
+
+	rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
+	    child);
+	if (rv == NULL)
+		return (NULL);
+	rman_set_rid(rv, *rid);
+
+	if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
+	    *rid, rv) != 0) {
+		rman_release_resource(rv);
+		return (NULL);
+	}
+	return (rv);
+}
+
+int
+ofw_pci_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	struct ofw_pci_softc *sc;
+	struct bus_space_tag *tag;
+
+	sc = device_get_softc(bus);
+	switch (type) {
+	case SYS_RES_IRQ:
+		return (bus_generic_activate_resource(bus, child, type, rid,
+		    r));
+	case SYS_RES_MEMORY:
+		tag = sparc64_alloc_bus_tag(r, &nexus_bustag,
+		    PCI_MEMORY_BUS_SPACE, NULL);
+		if (tag == NULL)
+			return (ENOMEM);
+		rman_set_bustag(r, tag);
+		rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] +
+		    rman_get_start(r));
+		break;
+	case SYS_RES_IOPORT:
+		rman_set_bustag(r, sc->sc_pci_iot);
+		rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] +
+		    rman_get_start(r));
+		break;
+	}
+	return (rman_activate_resource(r));
+}
+
+int
+ofw_pci_adjust_resource(device_t bus, device_t child, int type,
+    struct resource *r, u_long start, u_long end)
+{
+	struct ofw_pci_softc *sc;
+	struct rman *rm;
+
+	sc = device_get_softc(bus);
+	switch (type) {
+	case SYS_RES_IRQ:
+		return (bus_generic_adjust_resource(bus, child, type, r,
+		    start, end));
+	case SYS_RES_MEMORY:
+		rm = &sc->sc_pci_mem_rman;
+		break;
+	case SYS_RES_IOPORT:
+		rm = &sc->sc_pci_io_rman;
+		break;
+	default:
+		return (EINVAL);
+	}
+	if (rman_is_region_manager(r, rm) == 0)
+		return (EINVAL);
+	return (rman_adjust_resource(r, start, end));
+}
+
+bus_dma_tag_t
+ofw_pci_get_dma_tag(device_t bus, device_t child __unused)
+{
+	struct ofw_pci_softc *sc;
+
+	sc = device_get_softc(bus);
+	return (sc->sc_pci_dmat);
+}
+
+phandle_t
+ofw_pci_get_node(device_t bus, device_t child __unused)
+{
+	struct ofw_pci_softc *sc;
+
+	sc = device_get_softc(bus);
+	/* We only have one child, the PCI bus, which needs our own node. */
+	return (sc->sc_node);
+}


Property changes on: trunk/sys/sparc64/pci/ofw_pci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/ofw_pci.h
===================================================================
--- trunk/sys/sparc64/pci/ofw_pci.h	                        (rev 0)
+++ trunk/sys/sparc64/pci/ofw_pci.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,171 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1998, 1999 Eduardo E. Horvath
+ * Copyright (c) 2001, 2003 by Thomas Moestl <tmm at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: psychoreg.h,v 1.14 2008/05/30 02:29:37 mrg Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/pci/ofw_pci.h 292789 2015-12-27 19:37:47Z marius $
+ */
+
+#ifndef _SPARC64_PCI_OFW_PCI_H_
+#define	_SPARC64_PCI_OFW_PCI_H_
+
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "ofw_pci_if.h"
+
+typedef uint32_t ofw_pci_intr_t;
+
+/* PCI range child spaces. XXX: are these MI? */
+#define	OFW_PCI_CS_CONFIG	0x00
+#define	OFW_PCI_CS_IO		0x01
+#define	OFW_PCI_CS_MEM32	0x02
+#define	OFW_PCI_CS_MEM64	0x03
+#define	OFW_PCI_NUM_CS		4
+
+/* OFW device types */
+#define	OFW_TYPE_PCI		"pci"
+#define	OFW_TYPE_PCIE		"pciex"
+
+struct ofw_pci_msi_addr_ranges {
+	uint32_t	addr32_hi;
+	uint32_t	addr32_lo;
+	uint32_t	addr32_sz;
+	uint32_t	addr64_hi;
+	uint32_t	addr64_lo;
+	uint32_t	addr64_sz;
+};
+
+#define	OFW_PCI_MSI_ADDR_RANGE_32(r) \
+	(((uint64_t)(r)->addr32_hi << 32) | (uint64_t)(r)->addr32_lo)
+#define	OFW_PCI_MSI_ADDR_RANGE_64(r) \
+	(((uint64_t)(r)->addr64_hi << 32) | (uint64_t)(r)->addr64_lo)
+
+struct ofw_pci_msi_eq_to_devino {
+	uint32_t	eq_first;
+	uint32_t	eq_count;
+	uint32_t	devino_first;
+};
+
+struct ofw_pci_msi_ranges {
+	uint32_t	first;
+	uint32_t	count;
+};
+
+struct ofw_pci_ranges {
+	uint32_t	cspace;
+	uint32_t	child_hi;
+	uint32_t	child_lo;
+	uint32_t	phys_hi;
+	uint32_t	phys_lo;
+	uint32_t	size_hi;
+	uint32_t	size_lo;
+};
+
+#define	OFW_PCI_RANGE_CHILD(r) \
+	(((uint64_t)(r)->child_hi << 32) | (uint64_t)(r)->child_lo)
+#define	OFW_PCI_RANGE_PHYS(r) \
+	(((uint64_t)(r)->phys_hi << 32) | (uint64_t)(r)->phys_lo)
+#define	OFW_PCI_RANGE_SIZE(r) \
+	(((uint64_t)(r)->size_hi << 32) | (uint64_t)(r)->size_lo)
+#define	OFW_PCI_RANGE_CS(r)	(((r)->cspace >> 24) & 0x03)
+
+/* default values */
+#define	OFW_PCI_LATENCY	64
+
+/*
+ * Common and generic parts of host-PCI-bridge support
+ */
+
+struct ofw_pci_softc {
+	struct rman		sc_pci_mem_rman;
+	struct rman		sc_pci_io_rman;
+
+	bus_space_handle_t	sc_pci_bh[OFW_PCI_NUM_CS];
+	bus_space_tag_t		sc_pci_cfgt;
+	bus_space_tag_t		sc_pci_iot;
+	bus_dma_tag_t		sc_pci_dmat;
+
+	struct ofw_bus_iinfo	sc_pci_iinfo;
+
+	phandle_t		sc_node;
+
+	uint8_t			sc_pci_secbus;
+	uint8_t			sc_pci_subbus;
+};
+
+int ofw_pci_attach_common(device_t dev, bus_dma_tag_t dmat, u_long iosize,
+    u_long memsize);
+uint32_t ofw_pci_read_config_common(device_t dev, u_int regmax, u_long offset,
+    u_int bus, u_int slot, u_int func, u_int reg, int width);
+void ofw_pci_write_config_common(device_t dev, u_int regmax, u_long offset,
+    u_int bus, u_int slot, u_int func, u_int reg, uint32_t val, int width);
+ofw_pci_intr_t ofw_pci_route_interrupt_common(device_t bridge, device_t dev,
+    int pin);
+
+void ofw_pci_dmamap_sync_stst_order_common(void);
+
+bus_activate_resource_t ofw_pci_activate_resource;
+bus_adjust_resource_t ofw_pci_adjust_resource;
+bus_alloc_resource_t ofw_pci_alloc_resource;
+bus_get_dma_tag_t ofw_pci_get_dma_tag;
+bus_read_ivar_t ofw_pci_read_ivar;
+
+ofw_bus_get_node_t ofw_pci_get_node;
+
+#endif /* ! _SPARC64_PCI_OFW_PCI_H_ */


Property changes on: trunk/sys/sparc64/pci/ofw_pci.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/ofw_pci_if.m
===================================================================
--- trunk/sys/sparc64/pci/ofw_pci_if.m	                        (rev 0)
+++ trunk/sys/sparc64/pci/ofw_pci_if.m	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,49 @@
+#-
+# Copyright (c) 2001, 2003 by Thomas Moestl <tmm at FreeBSD.org>
+# Copyright (c) 2011 Marius Strobl <marius at 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, 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 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.
+#
+# $FreeBSD: stable/10/sys/sparc64/pci/ofw_pci_if.m 220038 2011-03-26 16:49:12Z marius $
+# $MidnightBSD$
+
+#include <sys/bus.h>
+
+INTERFACE ofw_pci;
+
+CODE {
+	static ofw_pci_setup_device_t ofw_pci_default_setup_device;
+
+	static void
+	ofw_pci_default_setup_device(device_t dev, device_t child)
+	{
+
+		if (device_get_parent(dev) != NULL)
+			OFW_PCI_SETUP_DEVICE(device_get_parent(dev), child);
+	}
+};
+
+# Setup a device further upward in the tree.
+METHOD void setup_device {
+	device_t dev;
+	device_t child;
+} DEFAULT ofw_pci_default_setup_device;


Property changes on: trunk/sys/sparc64/pci/ofw_pci_if.m
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/sparc64/pci/ofw_pcib.c
===================================================================
--- trunk/sys/sparc64/pci/ofw_pcib.c	                        (rev 0)
+++ trunk/sys/sparc64/pci/ofw_pcib.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,175 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1994,1995 Stefan Esser, Wolfgang StanglMeier
+ * Copyright (c) 2000 Michael Smith <msmith at freebsd.org>
+ * Copyright (c) 2000 BSDi
+ * Copyright (c) 2001 - 2003 Thomas Moestl <tmm at FreeBSD.org>
+ * Copyright (c) 2009 by Marius Strobl <marius at 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, 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.
+ *
+ *	from: FreeBSD: src/sys/dev/pci/pci_pci.c,v 1.3 2000/12/13
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/pci/ofw_pcib.c 247573 2013-03-01 20:34:02Z marius $");
+
+#include "opt_ofw_pci.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/openfirm.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcib_private.h>
+
+#include "pcib_if.h"
+
+#include <sparc64/pci/ofw_pci.h>
+#include <sparc64/pci/ofw_pcib_subr.h>
+
+#define	PCI_DEVID_ALI_M5249	0x524910b9
+#define	PCI_VENDOR_PLX		0x10b5
+
+static device_probe_t ofw_pcib_probe;
+static device_attach_t ofw_pcib_attach;
+static ofw_pci_setup_device_t ofw_pcib_setup_device;
+
+static device_method_t ofw_pcib_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ofw_pcib_probe),
+	DEVMETHOD(device_attach,	ofw_pcib_attach),
+
+	/* Bus interface */
+
+	/* pcib interface */
+	DEVMETHOD(pcib_route_interrupt, ofw_pcib_gen_route_interrupt),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_node,	ofw_pcib_gen_get_node),
+	DEVMETHOD(ofw_pci_setup_device, ofw_pcib_setup_device),
+
+	DEVMETHOD_END
+};
+
+static devclass_t pcib_devclass;
+
+DEFINE_CLASS_1(pcib, ofw_pcib_driver, ofw_pcib_methods,
+    sizeof(struct ofw_pcib_gen_softc), pcib_driver);
+EARLY_DRIVER_MODULE(ofw_pcib, pci, ofw_pcib_driver, pcib_devclass, NULL, NULL,
+    BUS_PASS_BUS);
+MODULE_DEPEND(ofw_pcib, pci, 1, 1, 1);
+
+static int
+ofw_pcib_probe(device_t dev)
+{
+	char desc[sizeof("OFW PCIe-PCIe bridge")];
+	const char *dtype, *pbdtype;
+
+#define	ISDTYPE(dtype, type)						\
+	(((dtype) != NULL) && strcmp((dtype), (type)) == 0)
+
+	if ((pci_get_class(dev) == PCIC_BRIDGE) &&
+	    (pci_get_subclass(dev) == PCIS_BRIDGE_PCI) &&
+	    ofw_bus_get_node(dev) != 0) {
+		dtype = ofw_bus_get_type(dev);
+		pbdtype = ofw_bus_get_type(device_get_parent(
+		    device_get_parent(dev)));
+		snprintf(desc, sizeof(desc), "OFW PCI%s-PCI%s bridge",
+		    ISDTYPE(pbdtype, OFW_TYPE_PCIE) ? "e" : "",
+		    ISDTYPE(dtype, OFW_TYPE_PCIE) ? "e" : "");
+		device_set_desc_copy(dev, desc);
+		return (BUS_PROBE_DEFAULT);
+	}
+
+#undef ISDTYPE
+
+	return (ENXIO);
+}
+
+static int
+ofw_pcib_attach(device_t dev)
+{
+	struct ofw_pcib_gen_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	switch (pci_get_devid(dev)) {
+	/*
+	 * The ALi M5249 found in Fire-based machines by definition must me
+	 * subtractive as they have a ISA bridge on their secondary side but
+	 * don't indicate this in the class code although the ISA I/O range
+	 * isn't included in their bridge decode.
+	 */
+	case PCI_DEVID_ALI_M5249:
+		sc->ops_pcib_sc.flags |= PCIB_SUBTRACTIVE;
+		break;
+	}
+
+	switch (pci_get_vendor(dev)) {
+	/*
+	 * Concurrently write the primary and secondary bus numbers in order
+	 * to work around a bug in PLX PEX 8114 causing the internal shadow
+	 * copies of these not to be updated when setting them bytewise.
+	 */
+	case PCI_VENDOR_PLX:
+		pci_write_config(dev, PCIR_PRIBUS_1,
+		    pci_read_config(dev, PCIR_SECBUS_1, 1) << 8 |
+		    pci_read_config(dev, PCIR_PRIBUS_1, 1), 2);
+		break;
+	}
+
+	ofw_pcib_gen_setup(dev);
+	pcib_attach_common(dev);
+	device_add_child(dev, "pci", -1);
+	return (bus_generic_attach(dev));
+}
+
+static void
+ofw_pcib_setup_device(device_t bus, device_t child)
+{
+	int i;
+	uint16_t reg;
+
+	switch (pci_get_vendor(bus)) {
+	/*
+	 * For PLX PEX 8532 issue 64 TLPs to the child from the downstream
+	 * port to the child device in order to work around a hardware bug.
+	 */
+	case PCI_VENDOR_PLX:
+		for (i = 0, reg = 0; i < 64; i++)
+			reg |= pci_get_devid(child);
+		break;
+	}
+
+	OFW_PCI_SETUP_DEVICE(device_get_parent(bus), child);
+}


Property changes on: trunk/sys/sparc64/pci/ofw_pcib.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/ofw_pcib_subr.c
===================================================================
--- trunk/sys/sparc64/pci/ofw_pcib_subr.c	                        (rev 0)
+++ trunk/sys/sparc64/pci/ofw_pcib_subr.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,108 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 by Thomas Moestl <tmm at 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, 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 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/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/pci/ofw_pcib_subr.c 266020 2014-05-14 14:17:51Z ian $");
+
+#include "opt_ofw_pci.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcib_private.h>
+
+#include "pcib_if.h"
+
+#include <sparc64/pci/ofw_pci.h>
+#include <sparc64/pci/ofw_pcib_subr.h>
+
+void
+ofw_pcib_gen_setup(device_t bridge)
+{
+	struct ofw_pcib_gen_softc *sc;
+
+	sc = device_get_softc(bridge);
+	sc->ops_pcib_sc.dev = bridge;
+	sc->ops_node = ofw_bus_get_node(bridge);
+	KASSERT(sc->ops_node != 0,
+	    ("ofw_pcib_gen_setup: no ofw pci parent bus!"));
+
+	ofw_bus_setup_iinfo(sc->ops_node, &sc->ops_iinfo,
+	    sizeof(ofw_pci_intr_t));
+}
+
+int
+ofw_pcib_gen_route_interrupt(device_t bridge, device_t dev, int intpin)
+{
+	struct ofw_pcib_gen_softc *sc;
+	struct ofw_bus_iinfo *ii;
+	struct ofw_pci_register reg;
+	ofw_pci_intr_t pintr, mintr;
+
+	sc = device_get_softc(bridge);
+	ii = &sc->ops_iinfo;
+	if (ii->opi_imapsz > 0) {
+		pintr = intpin;
+		if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), ii, &reg,
+		    sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
+		    NULL)) {
+			/*
+			 * If we've found a mapping, return it and don't map
+			 * it again on higher levels - that causes problems
+			 * in some cases, and never seems to be required.
+			 */
+			return (mintr);
+		}
+	} else if (intpin >= 1 && intpin <= 4) {
+		/*
+		 * When an interrupt map is missing, we need to do the
+		 * standard PCI swizzle and continue mapping at the parent.
+		 */
+		return (pcib_route_interrupt(bridge, dev, intpin));
+	}
+	/* Try at the parent. */
+	return (PCIB_ROUTE_INTERRUPT(device_get_parent(device_get_parent(
+	    bridge)), bridge, intpin));
+}
+
+phandle_t
+ofw_pcib_gen_get_node(device_t bridge, device_t dev)
+{
+	struct ofw_pcib_gen_softc *sc;
+
+	sc = device_get_softc(bridge);
+	return (sc->ops_node);
+}


Property changes on: trunk/sys/sparc64/pci/ofw_pcib_subr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/ofw_pcib_subr.h
===================================================================
--- trunk/sys/sparc64/pci/ofw_pcib_subr.h	                        (rev 0)
+++ trunk/sys/sparc64/pci/ofw_pcib_subr.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,47 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 by Thomas Moestl <tmm at 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, 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 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/pci/ofw_pcib_subr.h 178279 2008-04-17 12:38:00Z marius $
+ */
+
+#ifndef _SPARC64_PCI_OFW_PCI_SUBR_H
+#define	_SPARC64_PCI_OFW_PCI_SUBR_H
+
+struct ofw_pcib_gen_softc {
+	/*
+	 * This is here so that we can use pci bridge methods, too - the
+	 * generic routines only need the dev, secbus and subbus members
+	 * filled.
+	 */
+	struct pcib_softc	ops_pcib_sc;
+	phandle_t		ops_node;
+	struct ofw_bus_iinfo	ops_iinfo;
+};
+
+void ofw_pcib_gen_setup(device_t);
+pcib_route_interrupt_t ofw_pcib_gen_route_interrupt;
+ofw_bus_get_node_t ofw_pcib_gen_get_node;
+
+#endif /* !_SPARC64_PCI_OFW_PCI_SUBR_H */


Property changes on: trunk/sys/sparc64/pci/ofw_pcib_subr.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/ofw_pcibus.c
===================================================================
--- trunk/sys/sparc64/pci/ofw_pcibus.c	                        (rev 0)
+++ trunk/sys/sparc64/pci/ofw_pcibus.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,355 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1997, Stefan Esser <se at freebsd.org>
+ * Copyright (c) 2000, Michael Smith <msmith at freebsd.org>
+ * Copyright (c) 2000, BSDi
+ * Copyright (c) 2003, Thomas Moestl <tmm at FreeBSD.org>
+ * Copyright (c) 2005 - 2009 Marius Strobl <marius at 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/pci/ofw_pcibus.c 330938 2018-03-14 19:04:40Z jhb $");
+
+#include "opt_ofw_pci.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+#include <sys/module.h>
+#include <sys/pciio.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#ifndef SUN4V
+#include <machine/bus_common.h>
+#include <machine/iommureg.h>
+#endif
+#include <machine/resource.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pci_private.h>
+
+#include <sparc64/pci/ofw_pci.h>
+
+#include "pcib_if.h"
+#include "pci_if.h"
+
+/* Helper functions */
+static void ofw_pcibus_setup_device(device_t bridge, uint32_t clock,
+    u_int busno, u_int slot, u_int func);
+
+/* Methods */
+static bus_child_deleted_t ofw_pcibus_child_deleted;
+static bus_child_pnpinfo_str_t ofw_pcibus_pnpinfo_str;
+static device_attach_t ofw_pcibus_attach;
+static device_probe_t ofw_pcibus_probe;
+static ofw_bus_get_devinfo_t ofw_pcibus_get_devinfo;
+static pci_assign_interrupt_t ofw_pcibus_assign_interrupt;
+
+static device_method_t ofw_pcibus_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ofw_pcibus_probe),
+	DEVMETHOD(device_attach,	ofw_pcibus_attach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_child_deleted,	ofw_pcibus_child_deleted),
+	DEVMETHOD(bus_child_pnpinfo_str, ofw_pcibus_pnpinfo_str),
+
+	/* PCI interface */
+	DEVMETHOD(pci_assign_interrupt, ofw_pcibus_assign_interrupt),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	ofw_pcibus_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	DEVMETHOD_END
+};
+
+struct ofw_pcibus_devinfo {
+	struct pci_devinfo	opd_dinfo;
+	struct ofw_bus_devinfo	opd_obdinfo;
+};
+
+static devclass_t pci_devclass;
+
+DEFINE_CLASS_1(pci, ofw_pcibus_driver, ofw_pcibus_methods,
+    sizeof(struct pci_softc), pci_driver);
+EARLY_DRIVER_MODULE(ofw_pcibus, pcib, ofw_pcibus_driver, pci_devclass, 0, 0,
+    BUS_PASS_BUS);
+MODULE_VERSION(ofw_pcibus, 1);
+MODULE_DEPEND(ofw_pcibus, pci, 1, 1, 1);
+
+static int
+ofw_pcibus_probe(device_t dev)
+{
+
+	if (ofw_bus_get_node(dev) == -1)
+		return (ENXIO);
+	device_set_desc(dev, "OFW PCI bus");
+
+	return (0);
+}
+
+/*
+ * Perform miscellaneous setups the firmware usually does not do for us.
+ */
+static void
+ofw_pcibus_setup_device(device_t bridge, uint32_t clock, u_int busno,
+    u_int slot, u_int func)
+{
+#define	CS_READ(n, w)							\
+	PCIB_READ_CONFIG(bridge, busno, slot, func, (n), (w))
+#define	CS_WRITE(n, v, w)						\
+	PCIB_WRITE_CONFIG(bridge, busno, slot, func, (n), (v), (w))
+
+#ifndef SUN4V
+	uint32_t reg;
+
+	/*
+	 * Initialize the latency timer register for busmaster devices to
+	 * work properly.  This is another task which the firmware doesn't
+	 * always perform.  The Min_Gnt register can be used to compute its
+	 * recommended value: it contains the desired latency in units of
+	 * 1/4 us assuming a clock rate of 33MHz.  To calculate the correct
+	 * latency timer value, the clock frequency of the bus (defaulting
+	 * to 33MHz) should be used and no wait states assumed.
+	 * For bridges, we additionally set up the bridge control and the
+	 * secondary latency registers.
+	 */
+	if ((CS_READ(PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) ==
+	    PCIM_HDRTYPE_BRIDGE) {
+		reg = CS_READ(PCIR_BRIDGECTL_1, 1);
+		reg |= PCIB_BCR_MASTER_ABORT_MODE | PCIB_BCR_SERR_ENABLE |
+		    PCIB_BCR_PERR_ENABLE;
+#ifdef OFW_PCI_DEBUG
+		device_printf(bridge,
+		    "bridge %d/%d/%d: control 0x%x -> 0x%x\n",
+		    busno, slot, func, CS_READ(PCIR_BRIDGECTL_1, 1), reg);
+#endif /* OFW_PCI_DEBUG */
+		CS_WRITE(PCIR_BRIDGECTL_1, reg, 1);
+
+		reg = OFW_PCI_LATENCY;
+#ifdef OFW_PCI_DEBUG
+		device_printf(bridge,
+		    "bridge %d/%d/%d: latency timer %d -> %d\n",
+		    busno, slot, func, CS_READ(PCIR_SECLAT_1, 1), reg);
+#endif /* OFW_PCI_DEBUG */
+		CS_WRITE(PCIR_SECLAT_1, reg, 1);
+	} else {
+		reg = CS_READ(PCIR_MINGNT, 1);
+		if ((int)reg > 0) {
+			switch (clock) {
+			case 33000000:
+				reg *= 8;
+				break;
+			case 66000000:
+				reg *= 4;
+				break;
+			}
+			reg = min(reg, 255);
+		} else
+			reg = OFW_PCI_LATENCY;
+	}
+#ifdef OFW_PCI_DEBUG
+	device_printf(bridge, "device %d/%d/%d: latency timer %d -> %d\n",
+	    busno, slot, func, CS_READ(PCIR_LATTIMER, 1), reg);
+#endif /* OFW_PCI_DEBUG */
+	CS_WRITE(PCIR_LATTIMER, reg, 1);
+
+	/*
+	 * Compute a value to write into the cache line size register.
+	 * The role of the streaming cache is unclear in write invalidate
+	 * transfers, so it is made sure that it's line size is always
+	 * reached.  Generally, the cache line size is fixed at 64 bytes
+	 * by Fireplane/Safari, JBus and UPA.
+	 */
+	CS_WRITE(PCIR_CACHELNSZ, STRBUF_LINESZ / sizeof(uint32_t), 1);
+#endif
+
+	/*
+	 * Ensure that ALi M5229 report the actual content of PCIR_PROGIF
+	 * and that IDE I/O is force enabled.  The former is done in order
+	 * to have unique behavior across revisions as some default to
+	 * hiding bits 4-6 for compliance with PCI 2.3.  The latter is done
+	 * as at least revision 0xc8 requires the PCIM_CMD_PORTEN bypass
+	 * to be always enabled as otherwise even enabling PCIM_CMD_PORTEN
+	 * results in an instant data access trap on Fire-based machines.
+	 * Thus these quirks have to be handled before pci(4) adds the maps.
+	 * Note that for older revisions bit 0 of register 0x50 enables the
+	 * internal IDE function instead of force enabling IDE I/O.
+	 */
+	if ((CS_READ(PCIR_VENDOR, 2) == 0x10b9 &&
+	    CS_READ(PCIR_DEVICE, 2) == 0x5229))
+		CS_WRITE(0x50, CS_READ(0x50, 1) | 0x3, 1);
+
+	/*
+	 * The preset in the intline register is usually wrong.  Reset
+	 * it to 255, so that the PCI code will reroute the interrupt if
+	 * needed.
+	 */
+	CS_WRITE(PCIR_INTLINE, PCI_INVALID_IRQ, 1);
+
+#undef CS_READ
+#undef CS_WRITE
+}
+
+static int
+ofw_pcibus_attach(device_t dev)
+{
+	device_t pcib;
+	struct ofw_pci_register pcir;
+	struct ofw_pcibus_devinfo *dinfo;
+	phandle_t node, child;
+	uint32_t clock;
+	u_int busno, domain, func, slot;
+	int error;
+
+	error = pci_attach_common(dev);
+	if (error)
+		return (error);
+	pcib = device_get_parent(dev);
+	domain = pcib_get_domain(dev);
+	busno = pcib_get_bus(dev);
+	node = ofw_bus_get_node(dev);
+
+	/*
+	 * Add the PCI side of the host-PCI bridge itself to the bus.
+	 * Note that we exclude the host-PCIe bridges here as these
+	 * have no configuration space implemented themselves.
+	 */
+	if (strcmp(device_get_name(device_get_parent(pcib)), "nexus") == 0 &&
+	    ofw_bus_get_type(pcib) != NULL &&
+	    strcmp(ofw_bus_get_type(pcib), OFW_TYPE_PCIE) != 0 &&
+	    (dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
+	    domain, busno, 0, 0, sizeof(*dinfo))) != NULL) {
+		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, node) != 0)
+			pci_freecfg((struct pci_devinfo *)dinfo);
+		else
+			pci_add_child(dev, (struct pci_devinfo *)dinfo);
+	}
+
+	if (OF_getprop(ofw_bus_get_node(pcib), "clock-frequency", &clock,
+	    sizeof(clock)) == -1)
+		clock = 33000000;
+	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+		if (OF_getprop(child, "reg", &pcir, sizeof(pcir)) == -1)
+			continue;
+		slot = OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi);
+		func = OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi);
+		/* Some OFW device trees contain dupes. */
+		if (pci_find_dbsf(domain, busno, slot, func) != NULL)
+			continue;
+		ofw_pcibus_setup_device(pcib, clock, busno, slot, func);
+		dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
+		    domain, busno, slot, func, sizeof(*dinfo));
+		if (dinfo == NULL)
+			continue;
+		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
+		    0) {
+			pci_freecfg((struct pci_devinfo *)dinfo);
+			continue;
+		}
+		pci_add_child(dev, (struct pci_devinfo *)dinfo);
+		OFW_PCI_SETUP_DEVICE(pcib, dinfo->opd_dinfo.cfg.dev);
+	}
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+ofw_pcibus_assign_interrupt(device_t dev, device_t child)
+{
+	ofw_pci_intr_t intr;
+	int isz;
+
+	isz = OF_getprop(ofw_bus_get_node(child), "interrupts", &intr,
+	    sizeof(intr));
+	if (isz != sizeof(intr)) {
+		/* No property; our best guess is the intpin. */
+		intr = pci_get_intpin(child);
+#ifndef SUN4V
+	} else if (intr >= 255) {
+		/*
+		 * A fully specified interrupt (including IGN), as present on
+		 * SPARCengine Ultra AX and E450.  Extract the INO and return
+		 * it.
+		 */
+		return (INTINO(intr));
+#endif
+	}
+	/*
+	 * If we got intr from a property, it may or may not be an intpin.
+	 * For on-board devices, it frequently is not, and is completely out
+	 * of the valid intpin range.  For PCI slots, it hopefully is,
+	 * otherwise we will have trouble interfacing with non-OFW buses
+	 * such as cardbus.
+	 * Since we cannot tell which it is without violating layering, we
+	 * will always use the route_interrupt method, and treat exceptions
+	 * on the level they become apparent.
+	 */
+	return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, intr));
+}
+
+static const struct ofw_bus_devinfo *
+ofw_pcibus_get_devinfo(device_t bus, device_t dev)
+{
+	struct ofw_pcibus_devinfo *dinfo;
+
+	dinfo = device_get_ivars(dev);
+	return (&dinfo->opd_obdinfo);
+}
+
+static void
+ofw_pcibus_child_deleted(device_t dev, device_t child)
+{
+	struct ofw_pcibus_devinfo *dinfo;
+
+	dinfo = device_get_ivars(dev);
+	ofw_bus_gen_destroy_devinfo(&dinfo->opd_obdinfo);
+	pci_child_deleted(dev, child);
+}
+
+static int
+ofw_pcibus_pnpinfo_str(device_t dev, device_t child, char *buf,
+    size_t buflen)
+{
+
+	pci_child_pnpinfo_str_method(dev, child, buf, buflen);
+	if (ofw_bus_get_node(child) != -1)  {
+		strlcat(buf, " ", buflen); /* Separate info. */
+		ofw_bus_gen_child_pnpinfo_str(dev, child, buf, buflen);
+	}
+
+	return (0);
+}


Property changes on: trunk/sys/sparc64/pci/ofw_pcibus.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/psycho.c
===================================================================
--- trunk/sys/sparc64/pci/psycho.c	                        (rev 0)
+++ trunk/sys/sparc64/pci/psycho.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,1072 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm at FreeBSD.org>
+ * Copyright (c) 2005 - 2006 Marius Strobl <marius at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/pci/psycho.c 318273 2017-05-14 14:04:32Z marius $");
+
+/*
+ * Support for `Hummingbird' (UltraSPARC IIe), `Psycho' and `Psycho+'
+ * (UltraSPARC II) and `Sabre' (UltraSPARC IIi) UPA to PCI bridges.
+ */
+
+#include "opt_ofw_pci.h"
+#include "opt_psycho.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/reboot.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/bus_common.h>
+#include <machine/bus_private.h>
+#include <machine/iommureg.h>
+#include <machine/iommuvar.h>
+#include <machine/resource.h>
+#include <machine/ver.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <sparc64/pci/ofw_pci.h>
+#include <sparc64/pci/psychoreg.h>
+#include <sparc64/pci/psychovar.h>
+
+#include "pcib_if.h"
+
+static const struct psycho_desc *psycho_find_desc(const struct psycho_desc *,
+    const char *);
+static const struct psycho_desc *psycho_get_desc(device_t);
+static void psycho_set_intr(struct psycho_softc *, u_int, bus_addr_t,
+    driver_filter_t, driver_intr_t);
+static int psycho_find_intrmap(struct psycho_softc *, u_int, bus_addr_t *,
+    bus_addr_t *, u_long *);
+static void sabre_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map,
+    bus_dmasync_op_t op);
+static void psycho_intr_enable(void *);
+static void psycho_intr_disable(void *);
+static void psycho_intr_assign(void *);
+static void psycho_intr_clear(void *);
+
+/* Interrupt handlers */
+static driver_filter_t psycho_ue;
+static driver_filter_t psycho_ce;
+static driver_filter_t psycho_pci_bus;
+static driver_filter_t psycho_powerdebug;
+static driver_intr_t psycho_powerdown;
+static driver_intr_t psycho_overtemp;
+#ifdef PSYCHO_MAP_WAKEUP
+static driver_filter_t psycho_wakeup;
+#endif
+
+/* IOMMU support */
+static void psycho_iommu_init(struct psycho_softc *, int, uint32_t);
+
+/*
+ * Methods
+ */
+static device_probe_t psycho_probe;
+static device_attach_t psycho_attach;
+static bus_setup_intr_t psycho_setup_intr;
+static bus_alloc_resource_t psycho_alloc_resource;
+static pcib_maxslots_t psycho_maxslots;
+static pcib_read_config_t psycho_read_config;
+static pcib_write_config_t psycho_write_config;
+static pcib_route_interrupt_t psycho_route_interrupt;
+static ofw_pci_setup_device_t psycho_setup_device;
+
+static device_method_t psycho_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		psycho_probe),
+	DEVMETHOD(device_attach,	psycho_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	ofw_pci_read_ivar),
+	DEVMETHOD(bus_setup_intr,	psycho_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_alloc_resource,	psycho_alloc_resource),
+	DEVMETHOD(bus_activate_resource, ofw_pci_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	ofw_pci_adjust_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+	DEVMETHOD(bus_get_dma_tag,	ofw_pci_get_dma_tag),
+
+	/* pcib interface */
+	DEVMETHOD(pcib_maxslots,	psycho_maxslots),
+	DEVMETHOD(pcib_read_config,	psycho_read_config),
+	DEVMETHOD(pcib_write_config,	psycho_write_config),
+	DEVMETHOD(pcib_route_interrupt,	psycho_route_interrupt),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_node,	ofw_pci_get_node),
+
+	/* ofw_pci interface */
+	DEVMETHOD(ofw_pci_setup_device,	psycho_setup_device),
+
+	DEVMETHOD_END
+};
+
+static devclass_t psycho_devclass;
+
+DEFINE_CLASS_0(pcib, psycho_driver, psycho_methods,
+    sizeof(struct psycho_softc));
+EARLY_DRIVER_MODULE(psycho, nexus, psycho_driver, psycho_devclass, NULL, NULL,
+    BUS_PASS_BUS);
+
+static SYSCTL_NODE(_hw, OID_AUTO, psycho, CTLFLAG_RD, 0, "psycho parameters");
+
+static u_int psycho_powerfail = 1;
+TUNABLE_INT("hw.psycho.powerfail", &psycho_powerfail);
+SYSCTL_UINT(_hw_psycho, OID_AUTO, powerfail, CTLFLAG_RDTUN, &psycho_powerfail,
+    0, "powerfail action (0: none, 1: shutdown (default), 2: debugger)");
+
+static SLIST_HEAD(, psycho_softc) psycho_softcs =
+    SLIST_HEAD_INITIALIZER(psycho_softcs);
+
+static const struct intr_controller psycho_ic = {
+	psycho_intr_enable,
+	psycho_intr_disable,
+	psycho_intr_assign,
+	psycho_intr_clear
+};
+
+struct psycho_icarg {
+	struct psycho_softc	*pica_sc;
+	bus_addr_t		pica_map;
+	bus_addr_t		pica_clr;
+};
+
+#define	PSYCHO_READ8(sc, off)						\
+	bus_read_8((sc)->sc_mem_res, (off))
+#define	PSYCHO_WRITE8(sc, off, v)					\
+	bus_write_8((sc)->sc_mem_res, (off), (v))
+#define	PCICTL_READ8(sc, off)						\
+	PSYCHO_READ8((sc), (sc)->sc_pcictl + (off))
+#define	PCICTL_WRITE8(sc, off, v)					\
+	PSYCHO_WRITE8((sc), (sc)->sc_pcictl + (off), (v))
+
+/*
+ * "Sabre" is the UltraSPARC IIi onboard UPA to PCI bridge.  It manages a
+ * single PCI bus and does not have a streaming buffer.  It often has an APB
+ * (advanced PCI bridge) connected to it, which was designed specifically for
+ * the IIi.  The APB lets the IIi handle two independent PCI buses, and
+ * appears as two "Simba"'s underneath the Sabre.
+ *
+ * "Hummingbird" is the UltraSPARC IIe onboard UPA to PCI bridge. It's
+ * basically the same as Sabre but without an APB underneath it.
+ *
+ * "Psycho" and "Psycho+" are dual UPA to PCI bridges.  They sit on the UPA
+ * bus and manage two PCI buses.  "Psycho" has two 64-bit 33MHz buses, while
+ * "Psycho+" controls both a 64-bit 33Mhz and a 64-bit 66Mhz PCI bus.  You
+ * will usually find a "Psycho+" since I don't think the original "Psycho"
+ * ever shipped, and if it did it would be in the U30.
+ *
+ * Each "Psycho" PCI bus appears as a separate OFW node, but since they are
+ * both part of the same IC, they only have a single register space.  As such,
+ * they need to be configured together, even though the autoconfiguration will
+ * attach them separately.
+ *
+ * On UltraIIi machines, "Sabre" itself usually takes pci0, with "Simba" often
+ * as pci1 and pci2, although they have been implemented with other PCI bus
+ * numbers on some machines.
+ *
+ * On UltraII machines, there can be any number of "Psycho+" ICs, each
+ * providing two PCI buses.
+ */
+
+struct psycho_desc {
+	const char	*pd_string;
+	int		pd_mode;
+	const char	*pd_name;
+};
+
+static const struct psycho_desc psycho_compats[] = {
+	{ "pci108e,8000", PSYCHO_MODE_PSYCHO,	"Psycho compatible" },
+	{ "pci108e,a000", PSYCHO_MODE_SABRE,	"Sabre compatible" },
+	{ "pci108e,a001", PSYCHO_MODE_SABRE,	"Hummingbird compatible" },
+	{ NULL,		  0,			NULL }
+};
+
+static const struct psycho_desc psycho_models[] = {
+	{ "SUNW,psycho",  PSYCHO_MODE_PSYCHO,	"Psycho" },
+	{ "SUNW,sabre",   PSYCHO_MODE_SABRE,	"Sabre" },
+	{ NULL,		  0,			NULL }
+};
+
+static const struct psycho_desc *
+psycho_find_desc(const struct psycho_desc *table, const char *string)
+{
+	const struct psycho_desc *desc;
+
+	if (string == NULL)
+		return (NULL);
+	for (desc = table; desc->pd_string != NULL; desc++)
+		if (strcmp(desc->pd_string, string) == 0)
+			return (desc);
+	return (NULL);
+}
+
+static const struct psycho_desc *
+psycho_get_desc(device_t dev)
+{
+	const struct psycho_desc *rv;
+
+	rv = psycho_find_desc(psycho_models, ofw_bus_get_model(dev));
+	if (rv == NULL)
+		rv = psycho_find_desc(psycho_compats,
+		    ofw_bus_get_compat(dev));
+	return (rv);
+}
+
+static int
+psycho_probe(device_t dev)
+{
+	const char *dtype;
+
+	dtype = ofw_bus_get_type(dev);
+	if (dtype != NULL && strcmp(dtype, OFW_TYPE_PCI) == 0 &&
+	    psycho_get_desc(dev) != NULL) {
+		device_set_desc(dev, "U2P UPA-PCI bridge");
+		return (0);
+	}
+	return (ENXIO);
+}
+
+static int
+psycho_attach(device_t dev)
+{
+	struct psycho_icarg *pica;
+	struct psycho_softc *asc, *sc, *osc;
+	const struct psycho_desc *desc;
+	bus_addr_t intrclr, intrmap;
+	bus_dma_tag_t dmat;
+	uint64_t csr, dr;
+	phandle_t node;
+	uint32_t dvmabase, prop;
+	u_int rerun, ver;
+	int i, j;
+
+	node = ofw_bus_get_node(dev);
+	sc = device_get_softc(dev);
+	desc = psycho_get_desc(dev);
+
+	sc->sc_dev = dev;
+	sc->sc_mode = desc->pd_mode;
+
+	/*
+	 * The Psycho gets three register banks:
+	 * (0) per-PBM configuration and status registers
+	 * (1) per-PBM PCI configuration space, containing only the
+	 *     PBM 256-byte PCI header
+	 * (2) the shared Psycho configuration registers
+	 */
+	if (sc->sc_mode == PSYCHO_MODE_PSYCHO) {
+		i = 2;
+		sc->sc_pcictl =
+		    bus_get_resource_start(dev, SYS_RES_MEMORY, 0) -
+		    bus_get_resource_start(dev, SYS_RES_MEMORY, 2);
+		switch (sc->sc_pcictl) {
+		case PSR_PCICTL0:
+			sc->sc_half = 0;
+			break;
+		case PSR_PCICTL1:
+			sc->sc_half = 1;
+			break;
+		default:
+			panic("%s: bogus PCI control register location",
+			    __func__);
+			/* NOTREACHED */
+		}
+	} else {
+		i = 0;
+		sc->sc_pcictl = PSR_PCICTL0;
+		sc->sc_half = 0;
+	}
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i,
+	    (sc->sc_mode == PSYCHO_MODE_PSYCHO ? RF_SHAREABLE : 0) |
+	    RF_ACTIVE);
+	if (sc->sc_mem_res == NULL)
+		panic("%s: could not allocate registers", __func__);
+
+	/*
+	 * Match other Psychos that are already configured against
+	 * the base physical address.  This will be the same for a
+	 * pair of devices that share register space.
+	 */
+	osc = NULL;
+	SLIST_FOREACH(asc, &psycho_softcs, sc_link) {
+		if (rman_get_start(asc->sc_mem_res) ==
+		    rman_get_start(sc->sc_mem_res)) {
+			/* Found partner. */
+			osc = asc;
+			break;
+		}
+	}
+	if (osc == NULL) {
+		sc->sc_mtx = malloc(sizeof(*sc->sc_mtx), M_DEVBUF,
+		    M_NOWAIT | M_ZERO);
+		if (sc->sc_mtx == NULL)
+			panic("%s: could not malloc mutex", __func__);
+		mtx_init(sc->sc_mtx, "pcib_mtx", NULL, MTX_SPIN);
+	} else {
+		if (sc->sc_mode != PSYCHO_MODE_PSYCHO)
+			panic("%s: no partner expected", __func__);
+		if (mtx_initialized(osc->sc_mtx) == 0)
+			panic("%s: mutex not initialized", __func__);
+		sc->sc_mtx = osc->sc_mtx;
+	}
+	SLIST_INSERT_HEAD(&psycho_softcs, sc, sc_link);
+
+	csr = PSYCHO_READ8(sc, PSR_CS);
+	ver = PSYCHO_GCSR_VERS(csr);
+	sc->sc_ign = 0x1f; /* Hummingbird/Sabre IGN is always 0x1f. */
+	if (sc->sc_mode == PSYCHO_MODE_PSYCHO)
+		sc->sc_ign = PSYCHO_GCSR_IGN(csr);
+	if (OF_getprop(node, "clock-frequency", &prop, sizeof(prop)) == -1)
+		prop = 33000000;
+
+	device_printf(dev,
+	    "%s, impl %d, version %d, IGN %#x, bus %c, %dMHz\n",
+	    desc->pd_name, (u_int)PSYCHO_GCSR_IMPL(csr), ver, sc->sc_ign,
+	    'A' + sc->sc_half, prop / 1000 / 1000);
+
+	/* Set up the PCI control and PCI diagnostic registers. */
+
+	csr = PCICTL_READ8(sc, PCR_CS);
+	csr &= ~PCICTL_ARB_PARK;
+	if (OF_getproplen(node, "no-bus-parking") < 0)
+		csr |= PCICTL_ARB_PARK;
+
+	/* Workarounds for version specific bugs. */
+	dr = PCICTL_READ8(sc, PCR_DIAG);
+	switch (ver) {
+	case 0:
+		dr |= DIAG_RTRY_DIS;
+		dr &= ~DIAG_DWSYNC_DIS;
+		rerun = 0;
+		break;
+	case 1:
+		csr &= ~PCICTL_ARB_PARK;
+		dr |= DIAG_RTRY_DIS | DIAG_DWSYNC_DIS;
+		rerun = 0;
+		break;
+	default:
+		dr |= DIAG_DWSYNC_DIS;
+		dr &= ~DIAG_RTRY_DIS;
+		rerun = 1;
+		break;
+	}
+
+	csr |= PCICTL_ERRINTEN | PCICTL_ARB_4;
+	csr &= ~(PCICTL_SBHINTEN | PCICTL_WAKEUPEN);
+#ifdef PSYCHO_DEBUG
+	device_printf(dev, "PCI CSR 0x%016llx -> 0x%016llx\n",
+	    (unsigned long long)PCICTL_READ8(sc, PCR_CS),
+	    (unsigned long long)csr);
+#endif
+	PCICTL_WRITE8(sc, PCR_CS, csr);
+
+	dr &= ~DIAG_ISYNC_DIS;
+#ifdef PSYCHO_DEBUG
+	device_printf(dev, "PCI DR 0x%016llx -> 0x%016llx\n",
+	    (unsigned long long)PCICTL_READ8(sc, PCR_DIAG),
+	    (unsigned long long)dr);
+#endif
+	PCICTL_WRITE8(sc, PCR_DIAG, dr);
+
+	if (sc->sc_mode == PSYCHO_MODE_SABRE) {
+		/* Use the PROM preset for now. */
+		csr = PCICTL_READ8(sc, PCR_TAS);
+		if (csr == 0)
+			panic("%s: Hummingbird/Sabre TAS not initialized.",
+			    __func__);
+		dvmabase = (ffs(csr) - 1) << PCITAS_ADDR_SHIFT;
+	} else
+		dvmabase = -1;
+
+	/*
+	 * If we're a Hummingbird/Sabre or the first of a pair of Psychos
+	 * to arrive here, do the interrupt setup and start up the IOMMU.
+	 */
+	if (osc == NULL) {
+		/*
+		 * Hunt through all the interrupt mapping regs and register
+		 * our interrupt controller for the corresponding interrupt
+		 * vectors.  We do this early in order to be able to catch
+		 * stray interrupts.
+		 */
+		for (i = 0; i <= PSYCHO_MAX_INO; i++) {
+			if (psycho_find_intrmap(sc, i, &intrmap, &intrclr,
+			    NULL) == 0)
+				continue;
+			pica = malloc(sizeof(*pica), M_DEVBUF, M_NOWAIT);
+			if (pica == NULL)
+				panic("%s: could not allocate interrupt "
+				    "controller argument", __func__);
+			pica->pica_sc = sc;
+			pica->pica_map = intrmap;
+			pica->pica_clr = intrclr;
+#ifdef PSYCHO_DEBUG
+			/*
+			 * Enable all interrupts and clear all interrupt
+			 * states.  This aids the debugging of interrupt
+			 * routing problems.
+			 */
+			device_printf(dev,
+			    "intr map (INO %d, %s) %#lx: %#lx, clr: %#lx\n",
+			    i, intrmap <= PSR_PCIB3_INT_MAP ? "PCI" : "OBIO",
+			    (u_long)intrmap, (u_long)PSYCHO_READ8(sc,
+			    intrmap), (u_long)intrclr);
+			PSYCHO_WRITE8(sc, intrmap, INTMAP_VEC(sc->sc_ign, i));
+			PSYCHO_WRITE8(sc, intrclr, INTCLR_IDLE);
+			PSYCHO_WRITE8(sc, intrmap,
+			    INTMAP_ENABLE(INTMAP_VEC(sc->sc_ign, i),
+			    PCPU_GET(mid)));
+#endif
+			j = intr_controller_register(INTMAP_VEC(sc->sc_ign,
+			    i), &psycho_ic, pica);
+			if (j != 0)
+				device_printf(dev, "could not register "
+				    "interrupt controller for INO %d (%d)\n",
+				    i, j);
+		}
+
+		if (sc->sc_mode == PSYCHO_MODE_PSYCHO)
+			sparc64_counter_init(device_get_nameunit(dev),
+			    rman_get_bustag(sc->sc_mem_res),
+			    rman_get_bushandle(sc->sc_mem_res), PSR_TC0);
+
+		/*
+		 * Set up IOMMU and PCI configuration if we're the first
+		 * of a pair of Psychos to arrive here or a Hummingbird
+		 * or Sabre.
+		 *
+		 * We should calculate a TSB size based on amount of RAM
+		 * and number of bus controllers and number and type of
+		 * child devices.
+		 *
+		 * For the moment, 32KB should be more than enough.
+		 */
+		sc->sc_is = malloc(sizeof(*sc->sc_is), M_DEVBUF, M_NOWAIT |
+		    M_ZERO);
+		if (sc->sc_is == NULL)
+			panic("%s: could not malloc IOMMU state", __func__);
+		sc->sc_is->is_flags = IOMMU_PRESERVE_PROM;
+		if (sc->sc_mode == PSYCHO_MODE_SABRE) {
+			sc->sc_dma_methods =
+			    malloc(sizeof(*sc->sc_dma_methods), M_DEVBUF,
+			    M_NOWAIT);
+			if (sc->sc_dma_methods == NULL)
+				panic("%s: could not malloc DMA methods",
+				    __func__);
+			memcpy(sc->sc_dma_methods, &iommu_dma_methods,
+			    sizeof(*sc->sc_dma_methods));
+			sc->sc_dma_methods->dm_dmamap_sync =
+			    sabre_dmamap_sync;
+			sc->sc_is->is_pmaxaddr =
+			    IOMMU_MAXADDR(SABRE_IOMMU_BITS);
+		} else {
+			sc->sc_dma_methods = &iommu_dma_methods;
+			sc->sc_is->is_pmaxaddr =
+			    IOMMU_MAXADDR(PSYCHO_IOMMU_BITS);
+		}
+		sc->sc_is->is_sb[0] = sc->sc_is->is_sb[1] = 0;
+		if (OF_getproplen(node, "no-streaming-cache") < 0)
+			sc->sc_is->is_sb[0] = sc->sc_pcictl + PCR_STRBUF;
+		sc->sc_is->is_flags |= (rerun != 1) ? IOMMU_RERUN_DISABLE : 0;
+		psycho_iommu_init(sc, 3, dvmabase);
+	} else {
+		/* Just copy IOMMU state, config tag and address. */
+		sc->sc_dma_methods = &iommu_dma_methods;
+		sc->sc_is = osc->sc_is;
+		if (OF_getproplen(node, "no-streaming-cache") < 0)
+			sc->sc_is->is_sb[1] = sc->sc_pcictl + PCR_STRBUF;
+		iommu_reset(sc->sc_is);
+	}
+
+	/* Create our DMA tag. */
+	if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
+	    sc->sc_is->is_pmaxaddr, ~0, NULL, NULL, sc->sc_is->is_pmaxaddr,
+	    0xff, 0xffffffff, 0, NULL, NULL, &dmat) != 0)
+		panic("%s: could not create PCI DMA tag", __func__);
+	dmat->dt_cookie = sc->sc_is;
+	dmat->dt_mt = sc->sc_dma_methods;
+
+	if (ofw_pci_attach_common(dev, dmat, PSYCHO_IO_SIZE,
+	    PSYCHO_MEM_SIZE) != 0)
+		panic("%s: ofw_pci_attach_common() failed", __func__);
+
+	/* Clear any pending PCI error bits. */
+	PCIB_WRITE_CONFIG(dev, sc->sc_ops.sc_pci_secbus, PCS_DEVICE, PCS_FUNC,
+	    PCIR_STATUS, PCIB_READ_CONFIG(dev, sc->sc_ops.sc_pci_secbus,
+	    PCS_DEVICE, PCS_FUNC, PCIR_STATUS, 2), 2);
+	PCICTL_WRITE8(sc, PCR_CS, PCICTL_READ8(sc, PCR_CS));
+	PCICTL_WRITE8(sc, PCR_AFS, PCICTL_READ8(sc, PCR_AFS));
+
+	if (osc == NULL) {
+		/*
+		 * Establish handlers for interesting interrupts...
+		 *
+		 * XXX We need to remember these and remove this to support
+		 * hotplug on the UPA/FHC bus.
+		 *
+		 * XXX Not all controllers have these, but installing them
+		 * is better than trying to sort through this mess.
+		 */
+		psycho_set_intr(sc, 1, PSR_UE_INT_MAP, psycho_ue, NULL);
+		psycho_set_intr(sc, 2, PSR_CE_INT_MAP, psycho_ce, NULL);
+		switch (psycho_powerfail) {
+		case 0:
+			break;
+		case 2:
+			psycho_set_intr(sc, 3, PSR_POWER_INT_MAP,
+			    psycho_powerdebug, NULL);
+			break;
+		default:
+			psycho_set_intr(sc, 3, PSR_POWER_INT_MAP, NULL,
+			    psycho_powerdown);
+			break;
+		}
+		if (sc->sc_mode == PSYCHO_MODE_PSYCHO) {
+			/*
+			 * Hummingbirds/Sabres do not have the following two
+			 * interrupts.
+			 */
+
+			/*
+			 * The spare hardware interrupt is used for the
+			 * over-temperature interrupt.
+			 */
+			psycho_set_intr(sc, 4, PSR_SPARE_INT_MAP, NULL,
+			    psycho_overtemp);
+#ifdef PSYCHO_MAP_WAKEUP
+			/*
+			 * psycho_wakeup() doesn't do anything useful right
+			 * now.
+			 */
+			psycho_set_intr(sc, 5, PSR_PWRMGT_INT_MAP,
+			    psycho_wakeup, NULL);
+#endif /* PSYCHO_MAP_WAKEUP */
+		}
+	}
+	/*
+	 * Register a PCI bus error interrupt handler according to which
+	 * half this is.  Hummingbird/Sabre don't have a PCI bus B error
+	 * interrupt but they are also only used for PCI bus A.
+	 */
+	psycho_set_intr(sc, 0, sc->sc_half == 0 ? PSR_PCIAERR_INT_MAP :
+	    PSR_PCIBERR_INT_MAP, psycho_pci_bus, NULL);
+
+	/*
+	 * Set the latency timer register as this isn't always done by the
+	 * firmware.
+	 */
+	PCIB_WRITE_CONFIG(dev, sc->sc_ops.sc_pci_secbus, PCS_DEVICE, PCS_FUNC,
+	    PCIR_LATTIMER, OFW_PCI_LATENCY, 1);
+
+	for (i = PCIR_VENDOR; i < PCIR_STATUS; i += sizeof(uint16_t))
+		le16enc(&sc->sc_pci_hpbcfg[i],
+		    bus_space_read_2(sc->sc_ops.sc_pci_cfgt,
+		    sc->sc_ops.sc_pci_bh[OFW_PCI_CS_CONFIG],
+		    PSYCHO_CONF_OFF(sc->sc_ops.sc_pci_secbus, PCS_DEVICE,
+		    PCS_FUNC, i)));
+	for (i = PCIR_REVID; i <= PCIR_BIST; i += sizeof(uint8_t))
+		sc->sc_pci_hpbcfg[i] = bus_space_read_1(sc->sc_ops.sc_pci_cfgt,
+		    sc->sc_ops.sc_pci_bh[OFW_PCI_CS_CONFIG], PSYCHO_CONF_OFF(
+		    sc->sc_ops.sc_pci_secbus, PCS_DEVICE, PCS_FUNC, i));
+
+	/*
+	 * On E250 the interrupt map entry for the EBus bridge is wrong,
+	 * causing incorrect interrupts to be assigned to some devices on
+	 * the EBus.  Work around it by changing our copy of the interrupt
+	 * map mask to perform a full comparison of the INO.  That way
+	 * the interrupt map entry for the EBus bridge won't match at all
+	 * and the INOs specified in the "interrupts" properties of the
+	 * EBus devices will be used directly instead.
+	 */
+	if (strcmp(sparc64_model, "SUNW,Ultra-250") == 0 &&
+	    sc->sc_ops.sc_pci_iinfo.opi_imapmsk != NULL)
+		*(ofw_pci_intr_t *)(&sc->sc_ops.sc_pci_iinfo.opi_imapmsk[
+		    sc->sc_ops.sc_pci_iinfo.opi_addrc]) = INTMAP_INO_MASK;
+
+	device_add_child(dev, "pci", -1);
+	return (bus_generic_attach(dev));
+}
+
+static void
+psycho_set_intr(struct psycho_softc *sc, u_int index, bus_addr_t intrmap,
+    driver_filter_t filt, driver_intr_t intr)
+{
+	u_long vec;
+	int rid;
+
+	rid = index;
+	sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev,
+	    SYS_RES_IRQ, &rid, RF_ACTIVE);
+	if (sc->sc_irq_res[index] == NULL && intrmap >= PSR_POWER_INT_MAP) {
+		/*
+		 * These interrupts aren't mandatory and not available
+		 * with all controllers (not even Psychos).
+		 */
+		return;
+	}
+	if (sc->sc_irq_res[index] == NULL ||
+	    INTIGN(vec = rman_get_start(sc->sc_irq_res[index])) !=
+	    sc->sc_ign ||
+	    INTVEC(PSYCHO_READ8(sc, intrmap)) != vec ||
+	    intr_vectors[vec].iv_ic != &psycho_ic ||
+	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index],
+	    INTR_TYPE_MISC | INTR_BRIDGE, filt, intr, sc,
+	    &sc->sc_ihand[index]) != 0)
+		panic("%s: failed to set up interrupt %d", __func__, index);
+}
+
+static int
+psycho_find_intrmap(struct psycho_softc *sc, u_int ino,
+    bus_addr_t *intrmapptr, bus_addr_t *intrclrptr, bus_addr_t *intrdiagptr)
+{
+	bus_addr_t intrclr, intrmap;
+	uint64_t diag;
+	int found;
+
+	/*
+	 * XXX we only compare INOs rather than INRs since the firmware may
+	 * not provide the IGN and the IGN is constant for all devices on
+	 * that PCI controller.
+	 * This could cause problems for the FFB/external interrupt which
+	 * has a full vector that can be set arbitrarily.
+	 */
+
+	if (ino > PSYCHO_MAX_INO) {
+		device_printf(sc->sc_dev, "out of range INO %d requested\n",
+		    ino);
+		return (0);
+	}
+
+	found = 0;
+	/* Hunt through OBIO first. */
+	diag = PSYCHO_READ8(sc, PSR_OBIO_INT_DIAG);
+	for (intrmap = PSR_SCSI_INT_MAP, intrclr = PSR_SCSI_INT_CLR;
+	    intrmap <= PSR_PWRMGT_INT_MAP; intrmap += 8, intrclr += 8,
+	    diag >>= 2) {
+		if (sc->sc_mode == PSYCHO_MODE_SABRE &&
+		    (intrmap == PSR_TIMER0_INT_MAP ||
+		    intrmap == PSR_TIMER1_INT_MAP ||
+		    intrmap == PSR_PCIBERR_INT_MAP ||
+		    intrmap == PSR_PWRMGT_INT_MAP))
+			continue;
+		if (INTINO(PSYCHO_READ8(sc, intrmap)) == ino) {
+			diag &= 2;
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found) {
+		diag = PSYCHO_READ8(sc, PSR_PCI_INT_DIAG);
+		/* Now do PCI interrupts. */
+		for (intrmap = PSR_PCIA0_INT_MAP, intrclr = PSR_PCIA0_INT_CLR;
+		    intrmap <= PSR_PCIB3_INT_MAP; intrmap += 8, intrclr += 32,
+		    diag >>= 8) {
+			if (sc->sc_mode == PSYCHO_MODE_PSYCHO &&
+			    (intrmap == PSR_PCIA2_INT_MAP ||
+			    intrmap == PSR_PCIA3_INT_MAP))
+				continue;
+			if (((PSYCHO_READ8(sc, intrmap) ^ ino) & 0x3c) == 0) {
+				intrclr += 8 * (ino & 3);
+				diag = (diag >> ((ino & 3) * 2)) & 2;
+				found = 1;
+				break;
+			}
+		}
+	}
+	if (intrmapptr != NULL)
+		*intrmapptr = intrmap;
+	if (intrclrptr != NULL)
+		*intrclrptr = intrclr;
+	if (intrdiagptr != NULL)
+		*intrdiagptr = diag;
+	return (found);
+}
+
+/*
+ * Interrupt handlers
+ */
+static int
+psycho_ue(void *arg)
+{
+	struct psycho_softc *sc = arg;
+	uint64_t afar, afsr;
+
+	afar = PSYCHO_READ8(sc, PSR_UE_AFA);
+	afsr = PSYCHO_READ8(sc, PSR_UE_AFS);
+	/*
+	 * On the UltraSPARC-IIi/IIe, IOMMU misses/protection faults cause
+	 * the AFAR to be set to the physical address of the TTE entry that
+	 * was invalid/write protected.  Call into the IOMMU code to have
+	 * them decoded to virtual I/O addresses.
+	 */
+	if ((afsr & UEAFSR_P_DTE) != 0)
+		iommu_decode_fault(sc->sc_is, afar);
+	panic("%s: uncorrectable DMA error AFAR %#lx AFSR %#lx",
+	    device_get_nameunit(sc->sc_dev), (u_long)afar, (u_long)afsr);
+	return (FILTER_HANDLED);
+}
+
+static int
+psycho_ce(void *arg)
+{
+	struct psycho_softc *sc = arg;
+	uint64_t afar, afsr;
+
+	mtx_lock_spin(sc->sc_mtx);
+	afar = PSYCHO_READ8(sc, PSR_CE_AFA);
+	afsr = PSYCHO_READ8(sc, PSR_CE_AFS);
+	device_printf(sc->sc_dev, "correctable DMA error AFAR %#lx "
+	    "AFSR %#lx\n", (u_long)afar, (u_long)afsr);
+	/* Clear the error bits that we caught. */
+	PSYCHO_WRITE8(sc, PSR_CE_AFS, afsr);
+	mtx_unlock_spin(sc->sc_mtx);
+	return (FILTER_HANDLED);
+}
+
+static int
+psycho_pci_bus(void *arg)
+{
+	struct psycho_softc *sc = arg;
+	uint64_t afar, afsr;
+
+	afar = PCICTL_READ8(sc, PCR_AFA);
+	afsr = PCICTL_READ8(sc, PCR_AFS);
+	panic("%s: PCI bus %c error AFAR %#lx AFSR %#lx",
+	    device_get_nameunit(sc->sc_dev), 'A' + sc->sc_half, (u_long)afar,
+	    (u_long)afsr);
+	return (FILTER_HANDLED);
+}
+
+static int
+psycho_powerdebug(void *arg __unused)
+{
+
+	kdb_enter(KDB_WHY_POWERFAIL, "powerfail");
+	return (FILTER_HANDLED);
+}
+
+static void
+psycho_powerdown(void *arg __unused)
+{
+	static int shutdown;
+
+	/* As the interrupt is cleared we may be called multiple times. */
+	if (shutdown != 0)
+		return;
+	shutdown++;
+	printf("Power Failure Detected: Shutting down NOW.\n");
+	shutdown_nice(RB_POWEROFF);
+}
+
+static void
+psycho_overtemp(void *arg __unused)
+{
+	static int shutdown;
+
+	/* As the interrupt is cleared we may be called multiple times. */
+	if (shutdown != 0)
+		return;
+	shutdown++;
+	printf("DANGER: OVER TEMPERATURE detected.\nShutting down NOW.\n");
+	shutdown_nice(RB_POWEROFF);
+}
+
+#ifdef PSYCHO_MAP_WAKEUP
+static int
+psycho_wakeup(void *arg)
+{
+	struct psycho_softc *sc = arg;
+
+	/* We don't really have a framework to deal with this properly. */
+	device_printf(sc->sc_dev, "power management wakeup\n");
+	return (FILTER_HANDLED);
+}
+#endif /* PSYCHO_MAP_WAKEUP */
+
+static void
+psycho_iommu_init(struct psycho_softc *sc, int tsbsize, uint32_t dvmabase)
+{
+	struct iommu_state *is = sc->sc_is;
+
+	/* Punch in our copies. */
+	is->is_bustag = rman_get_bustag(sc->sc_mem_res);
+	is->is_bushandle = rman_get_bushandle(sc->sc_mem_res);
+	is->is_iommu = PSR_IOMMU;
+	is->is_dtag = PSR_IOMMU_TLB_TAG_DIAG;
+	is->is_ddram = PSR_IOMMU_TLB_DATA_DIAG;
+	is->is_dqueue = PSR_IOMMU_QUEUE_DIAG;
+	is->is_dva = PSR_IOMMU_SVADIAG;
+	is->is_dtcmp = PSR_IOMMU_TLB_CMP_DIAG;
+
+	iommu_init(device_get_nameunit(sc->sc_dev), is, tsbsize, dvmabase, 0);
+}
+
+static int
+psycho_maxslots(device_t dev)
+{
+
+	/* XXX: is this correct? */
+	return (PCI_SLOTMAX);
+}
+
+static uint32_t
+psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
+    int width)
+{
+	struct psycho_softc *sc;
+
+	sc = device_get_softc(dev);
+	/*
+	 * The Hummingbird and Sabre bridges are picky in that they
+	 * only allow their config space to be accessed using the
+	 * "native" width of the respective register being accessed
+	 * and return semi-random other content of their config space
+	 * otherwise.  Given that the PCI specs don't say anything
+	 * about such a (unusual) limitation and lots of stuff expects
+	 * to be able to access the contents of the config space at
+	 * any width we allow just that.  We do this by using a copy
+	 * of the header of the bridge (the rest is all zero anyway)
+	 * read during attach (expect for PCIR_STATUS) in order to
+	 * simplify things.
+	 * The Psycho bridges contain a dupe of their header at 0x80
+	 * which we nullify that way also.
+	 */
+	if (bus == sc->sc_ops.sc_pci_secbus && slot == PCS_DEVICE &&
+	    func == PCS_FUNC) {
+		if (reg % width != 0)
+			return (-1);
+
+		if (reg >= sizeof(sc->sc_pci_hpbcfg))
+			return (0);
+
+		if ((reg < PCIR_STATUS && reg + width > PCIR_STATUS) ||
+		    reg == PCIR_STATUS || reg == PCIR_STATUS + 1)
+			le16enc(&sc->sc_pci_hpbcfg[PCIR_STATUS],
+			    bus_space_read_2(sc->sc_ops.sc_pci_cfgt,
+			    sc->sc_ops.sc_pci_bh[OFW_PCI_CS_CONFIG],
+			    PSYCHO_CONF_OFF(sc->sc_ops.sc_pci_secbus,
+			    PCS_DEVICE, PCS_FUNC, PCIR_STATUS)));
+
+		switch (width) {
+		case 1:
+			return (sc->sc_pci_hpbcfg[reg]);
+		case 2:
+			return (le16dec(&sc->sc_pci_hpbcfg[reg]));
+		case 4:
+			return (le32dec(&sc->sc_pci_hpbcfg[reg]));
+		}
+	}
+
+	return (ofw_pci_read_config_common(dev, PCI_REGMAX,
+	    PSYCHO_CONF_OFF(bus, slot, func, reg), bus, slot, func, reg,
+	    width));
+}
+
+static void
+psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, uint32_t val, int width)
+{
+
+	ofw_pci_write_config_common(dev, PCI_REGMAX, PSYCHO_CONF_OFF(bus,
+	    slot, func, reg), bus, slot, func, reg, val, width);
+}
+
+static int
+psycho_route_interrupt(device_t bridge, device_t dev, int pin)
+{
+	struct psycho_softc *sc;
+	bus_addr_t intrmap;
+	ofw_pci_intr_t mintr;
+
+	mintr = ofw_pci_route_interrupt_common(bridge, dev, pin);
+	if (PCI_INTERRUPT_VALID(mintr))
+		return (mintr);
+	/*
+	 * If this is outside of the range for an intpin, it's likely a full
+	 * INO, and no mapping is required at all; this happens on the U30,
+	 * where there's no interrupt map at the Psycho node.  Fortunately,
+	 * there seem to be no INOs in the intpin range on this boxen, so
+	 * this easy heuristics will do.
+	 */
+	if (pin > 4)
+		return (pin);
+	/*
+	 * Guess the INO; we always assume that this is a non-OBIO device,
+	 * and that pin is a "real" intpin number.  Determine the mapping
+	 * register to be used by the slot number.
+	 * We only need to do this on E450s and U30s, though; here, the
+	 * slot numbers for bus A are one-based, while those for bus B
+	 * seemingly have an offset of 2 (hence the factor of 3 below).
+	 */
+	sc = device_get_softc(bridge);
+	intrmap = PSR_PCIA0_INT_MAP +
+	    8 * (pci_get_slot(dev) - 1 + 3 * sc->sc_half);
+	mintr = INTINO(PSYCHO_READ8(sc, intrmap)) + pin - 1;
+	device_printf(bridge,
+	    "guessing interrupt %d for device %d.%d pin %d\n",
+	    (int)mintr, pci_get_slot(dev), pci_get_function(dev), pin);
+	return (mintr);
+}
+
+static void
+sabre_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
+{
+	struct iommu_state *is = dt->dt_cookie;
+
+	if ((map->dm_flags & DMF_LOADED) == 0)
+		return;
+
+	if ((op & BUS_DMASYNC_POSTREAD) != 0)
+		(void)bus_space_read_8(is->is_bustag, is->is_bushandle,
+		    PSR_DMA_WRITE_SYNC);
+
+	if ((op & BUS_DMASYNC_PREWRITE) != 0)
+		membar(Sync);
+}
+
+static void
+psycho_intr_enable(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct psycho_icarg *pica = iv->iv_icarg;
+
+	PSYCHO_WRITE8(pica->pica_sc, pica->pica_map,
+	    INTMAP_ENABLE(iv->iv_vec, iv->iv_mid));
+}
+
+static void
+psycho_intr_disable(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct psycho_icarg *pica = iv->iv_icarg;
+
+	PSYCHO_WRITE8(pica->pica_sc, pica->pica_map, iv->iv_vec);
+}
+
+static void
+psycho_intr_assign(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct psycho_icarg *pica = iv->iv_icarg;
+
+	PSYCHO_WRITE8(pica->pica_sc, pica->pica_map, INTMAP_TID(
+	    PSYCHO_READ8(pica->pica_sc, pica->pica_map), iv->iv_mid));
+}
+
+static void
+psycho_intr_clear(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct psycho_icarg *pica = iv->iv_icarg;
+
+	PSYCHO_WRITE8(pica->pica_sc, pica->pica_clr, INTCLR_IDLE);
+}
+
+static int
+psycho_setup_intr(device_t dev, device_t child, struct resource *ires,
+    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
+    void **cookiep)
+{
+	struct psycho_softc *sc;
+	u_long vec;
+
+	sc = device_get_softc(dev);
+	/*
+	 * Make sure the vector is fully specified and we registered
+	 * our interrupt controller for it.
+	 */
+	vec = rman_get_start(ires);
+	if (INTIGN(vec) != sc->sc_ign ||
+	    intr_vectors[vec].iv_ic != &psycho_ic) {
+		device_printf(dev, "invalid interrupt vector 0x%lx\n", vec);
+		return (EINVAL);
+	}
+	return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr,
+	    arg, cookiep));
+}
+
+static struct resource *
+psycho_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct psycho_softc *sc;
+
+	if (type == SYS_RES_IRQ) {
+		sc = device_get_softc(bus);
+		start = end = INTMAP_VEC(sc->sc_ign, end);
+	}
+	return (ofw_pci_alloc_resource(bus, child, type, rid, start, end,
+	    count, flags));
+}
+
+static void
+psycho_setup_device(device_t bus, device_t child)
+{
+	struct psycho_softc *sc;
+	uint32_t rev;
+
+	sc = device_get_softc(bus);
+	/*
+	 * Revision 0 EBus bridges have a bug which prevents them from
+	 * working when bus parking is enabled.
+	 */
+	if ((strcmp(ofw_bus_get_name(child), "ebus") == 0 ||
+	    strcmp(ofw_bus_get_name(child), "pci108e,1000") == 0) &&
+	    OF_getprop(ofw_bus_get_node(child), "revision-id", &rev,
+	    sizeof(rev)) > 0 && rev == 0)
+		PCICTL_WRITE8(sc, PCR_CS, PCICTL_READ8(sc, PCR_CS) &
+		    ~PCICTL_ARB_PARK);
+}


Property changes on: trunk/sys/sparc64/pci/psycho.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/psychoreg.h
===================================================================
--- trunk/sys/sparc64/pci/psychoreg.h	                        (rev 0)
+++ trunk/sys/sparc64/pci/psychoreg.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,329 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999 Matthew R. Green
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1998, 1999 Eduardo E. Horvath
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: psychoreg.h,v 1.14 2008/05/30 02:29:37 mrg Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/pci/psychoreg.h 292789 2015-12-27 19:37:47Z marius $
+ */
+
+#ifndef _SPARC64_PCI_PSYCHOREG_H_
+#define _SPARC64_PCI_PSYCHOREG_H_
+
+/*
+ * Sun4u PCI definitions.  Here's where we deal w/the machine
+ * dependencies of Psycho and the PCI controller on the UltraIIi.
+ *
+ * All PCI registers are bit-swapped, however they are not byte-swapped.
+ * This means that they must be accessed using little-endian access modes,
+ * either map the pages little-endian or use little-endian ASIs.
+ *
+ * PSYCHO implements two PCI buses, A and B.
+ */
+
+#define	PSYCHO_NINTR		6
+
+/*
+ * Psycho register offsets
+ *
+ * NB: FFB0 and FFB1 intr map regs also appear at 0x6000 and 0x8000
+ * respectively.
+ */
+#define	PSR_UPA_PORTID		0x0000	/* UPA port ID register */
+#define	PSR_UPA_CONFIG		0x0008	/* UPA config register */
+#define	PSR_CS			0x0010	/* PSYCHO control/status register */
+#define	PSR_ECCC		0x0020	/* ECC control register */
+#define	PSR_UE_AFS		0x0030	/* Uncorrectable Error AFSR */
+#define	PSR_UE_AFA		0x0038	/* Uncorrectable Error AFAR */
+#define	PSR_CE_AFS		0x0040	/* Correctable Error AFSR */
+#define	PSR_CE_AFA		0x0048	/* Correctable Error AFAR */
+#define	PSR_PM_CTL		0x0100	/* Performance monitor control reg */
+#define	PSR_PM_COUNT		0x0108	/* Performance monitor counter reg */
+#define	PSR_IOMMU		0x0200	/* IOMMU registers */
+#define	PSR_PCIA0_INT_MAP	0x0c00	/* PCI bus a slot 0 irq map reg */
+#define	PSR_PCIA1_INT_MAP	0x0c08	/* PCI bus a slot 1 irq map reg */
+#define	PSR_PCIA2_INT_MAP	0x0c10	/* PCI bus a slot 2 irq map reg (IIi) */
+#define	PSR_PCIA3_INT_MAP	0x0c18	/* PCI bus a slot 3 irq map reg (IIi) */
+#define	PSR_PCIB0_INT_MAP	0x0c20	/* PCI bus b slot 0 irq map reg */
+#define	PSR_PCIB1_INT_MAP	0x0c28	/* PCI bus b slot 1 irq map reg */
+#define	PSR_PCIB2_INT_MAP	0x0c30	/* PCI bus b slot 2 irq map reg */
+#define	PSR_PCIB3_INT_MAP	0x0c38	/* PCI bus b slot 3 irq map reg */
+#define	PSR_SCSI_INT_MAP	0x1000	/* SCSI interrupt map reg */
+#define	PSR_ETHER_INT_MAP	0x1008	/* ethernet interrupt map reg */
+#define	PSR_BPP_INT_MAP		0x1010	/* parallel interrupt map reg */
+#define	PSR_AUDIOR_INT_MAP	0x1018	/* audio record interrupt map reg */
+#define	PSR_AUDIOP_INT_MAP	0x1020	/* audio playback interrupt map reg */
+#define	PSR_POWER_INT_MAP	0x1028	/* power fail interrupt map reg */
+#define	PSR_SKBDMS_INT_MAP	0x1030	/* serial/kbd/mouse interrupt map reg */
+#define	PSR_FD_INT_MAP		0x1038	/* floppy interrupt map reg */
+#define	PSR_SPARE_INT_MAP	0x1040	/* spare interrupt map reg */
+#define	PSR_KBD_INT_MAP		0x1048	/* kbd [unused] interrupt map reg */
+#define	PSR_MOUSE_INT_MAP	0x1050	/* mouse [unused] interrupt map reg */
+#define	PSR_SERIAL_INT_MAP	0x1058	/* second serial interrupt map reg */
+#define	PSR_TIMER0_INT_MAP	0x1060	/* timer 0 interrupt map reg */
+#define	PSR_TIMER1_INT_MAP	0x1068	/* timer 1 interrupt map reg */
+#define	PSR_UE_INT_MAP		0x1070	/* UE interrupt map reg */
+#define	PSR_CE_INT_MAP		0x1078	/* CE interrupt map reg */
+#define	PSR_PCIAERR_INT_MAP	0x1080	/* PCI bus a error interrupt map reg */
+#define	PSR_PCIBERR_INT_MAP	0x1088	/* PCI bus b error interrupt map reg */
+#define	PSR_PWRMGT_INT_MAP	0x1090	/* power mgmt wake interrupt map reg */
+#define	PSR_FFB0_INT_MAP	0x1098	/* FFB0 graphics interrupt map reg */
+#define	PSR_FFB1_INT_MAP	0x10a0	/* FFB1 graphics interrupt map reg */
+/* Note: Clear interrupt 0 registers are not really used. */
+#define	PSR_PCIA0_INT_CLR	0x1400	/* PCI a slot 0 clear int regs 0..3 */
+#define	PSR_PCIA1_INT_CLR	0x1420	/* PCI a slot 1 clear int regs 0..3 */
+#define	PSR_PCIA2_INT_CLR	0x1440	/* PCI a slot 2 clear int regs 0..3 */
+#define	PSR_PCIA3_INT_CLR	0x1460	/* PCI a slot 3 clear int regs 0..3 */
+#define	PSR_PCIB0_INT_CLR	0x1480	/* PCI b slot 0 clear int regs 0..3 */
+#define	PSR_PCIB1_INT_CLR	0x14a0	/* PCI b slot 1 clear int regs 0..3 */
+#define	PSR_PCIB2_INT_CLR	0x14c0	/* PCI b slot 2 clear int regs 0..3 */
+#define	PSR_PCIB3_INT_CLR	0x14d0	/* PCI b slot 3 clear int regs 0..3 */
+#define	PSR_SCSI_INT_CLR	0x1800	/* SCSI clear int reg */
+#define	PSR_ETHER_INT_CLR	0x1808	/* ethernet clear int reg */
+#define	PSR_BPP_INT_CLR		0x1810	/* parallel clear int reg */
+#define	PSR_AUDIOR_INT_CLR	0x1818	/* audio record clear int reg */
+#define	PSR_AUDIOP_INT_CLR	0x1820	/* audio playback clear int reg */
+#define	PSR_POWER_INT_CLR	0x1828	/* power fail clear int reg */
+#define	PSR_SKBDMS_INT_CLR	0x1830	/* serial/kbd/mouse clear int reg */
+#define	PSR_FD_INT_CLR		0x1838	/* floppy clear int reg */
+#define	PSR_SPARE_INT_CLR	0x1840	/* spare clear int reg */
+#define	PSR_KBD_INT_CLR		0x1848	/* kbd [unused] clear int reg */
+#define	PSR_MOUSE_INT_CLR	0x1850	/* mouse [unused] clear int reg */
+#define	PSR_SERIAL_INT_CLR	0x1858	/* second serial clear int reg */
+#define	PSR_TIMER0_INT_CLR	0x1860	/* timer 0 clear int reg */
+#define	PSR_TIMER1_INT_CLR	0x1868	/* timer 1 clear int reg */
+#define	PSR_UE_INT_CLR		0x1870	/* UE clear int reg */
+#define	PSR_CE_INT_CLR		0x1878	/* CE clear int reg */
+#define	PSR_PCIAERR_INT_CLR	0x1880	/* PCI bus a error clear int reg */
+#define	PSR_PCIBERR_INT_CLR	0x1888	/* PCI bus b error clear int reg */
+#define	PSR_PWRMGT_INT_CLR	0x1890	/* power mgmt wake clr interrupt reg */
+#define	PSR_INTR_RETRY_TIM	0x1a00	/* interrupt retry timer */
+#define	PSR_TC0			0x1c00	/* timer/counter 0 */
+#define	PSR_TC1			0x1c10	/* timer/counter 1 */
+#define	PSR_DMA_WRITE_SYNC	0x1c20	/* PCI DMA write sync register (IIi) */
+#define	PSR_PCICTL0		0x2000	/* PCICTL registers for 1st Psycho */
+#define	PSR_PCICTL1		0x4000	/* PCICTL registers for 2nd Psycho */
+#define	PSR_DMA_SCB_DIAG0	0xa000	/* DMA scoreboard diag reg 0 */
+#define	PSR_DMA_SCB_DIAG1	0xa008	/* DMA scoreboard diag reg 1 */
+#define	PSR_IOMMU_SVADIAG	0xa400	/* IOMMU virtual addr diag reg */
+#define	PSR_IOMMU_TLB_CMP_DIAG	0xa408	/* IOMMU TLB tag compare diag reg */
+#define	PSR_IOMMU_QUEUE_DIAG	0xa500	/* IOMMU LRU queue diag regs 0..15 */
+#define	PSR_IOMMU_TLB_TAG_DIAG	0xa580	/* TLB tag diag regs 0..15 */
+#define	PSR_IOMMU_TLB_DATA_DIAG	0xa600	/* TLB data RAM diag regs 0..15 */
+#define	PSR_PCI_INT_DIAG	0xa800	/* PCI int state diag reg */
+#define	PSR_OBIO_INT_DIAG	0xa808	/* OBIO and misc int state diag reg */
+#define	PSR_STRBUF_DIAG		0xb000	/* Streaming buffer diag regs */
+
+/*
+ * Here is the rest of the map, which we're not specifying:
+ *
+ * 1fe.0100.0000 - 1fe.01ff.ffff	PCI configuration space
+ * 1fe.0100.0000 - 1fe.0100.00ff	PCI B configuration header
+ * 1fe.0101.0000 - 1fe.0101.00ff	PCI A configuration header
+ * 1fe.0200.0000 - 1fe.0200.ffff	PCI A I/O space
+ * 1fe.0201.0000 - 1fe.0201.ffff	PCI B I/O space
+ * 1ff.0000.0000 - 1ff.7fff.ffff	PCI A memory space
+ * 1ff.8000.0000 - 1ff.ffff.ffff	PCI B memory space
+ *
+ * NB: Config and I/O space can use 1-4 byte accesses, not 8 byte
+ * accesses.  Memory space can use any sized accesses.
+ *
+ * Note that the SUNW,sabre/SUNW,simba combinations found on the
+ * Ultra5 and Ultra10 machines uses slightly differrent addresses
+ * than the above.  This is mostly due to the fact that the APB is
+ * a multi-function PCI device with two PCI bridges, and the U2P is
+ * two separate PCI bridges.  It uses the same PCI configuration
+ * space, though the configuration header for each PCI bus is
+ * located differently due to the SUNW,simba PCI busses being
+ * function 0 and function 1 of the APB, whereas the Psycho's are
+ * each their own PCI device.  The I/O and memory spaces are each
+ * split into 8 equally sized areas (8x2MB blocks for I/O space,
+ * and 8x512MB blocks for memory space).  These are allocated in to
+ * either PCI A or PCI B, or neither in the APB's `I/O Address Map
+ * Register A/B' (0xde) and `Memory Address Map Register A/B' (0xdf)
+ * registers of each Simba.  We must ensure that both of the
+ * following are correct (the prom should do this for us):
+ *
+ *    (PCI A Memory Address Map) & (PCI B Memory Address Map) == 0
+ *
+ *    (PCI A I/O Address Map) & (PCI B I/O Address Map) == 0
+ *
+ * 1fe.0100.0000 - 1fe.01ff.ffff	PCI configuration space
+ * 1fe.0100.0800 - 1fe.0100.08ff	PCI B configuration header
+ * 1fe.0100.0900 - 1fe.0100.09ff	PCI A configuration header
+ * 1fe.0200.0000 - 1fe.02ff.ffff	PCI I/O space (divided)
+ * 1ff.0000.0000 - 1ff.ffff.ffff	PCI memory space (divided)
+ */
+
+/*
+ * PSR_CS defines:
+ *
+ * 63     59     55     50     45     4        3       2     1      0
+ * +------+------+------+------+--//---+--------+-------+-----+------+
+ * | IMPL | VERS | MID  | IGN  |  xxx  | APCKEN | APERR | IAP | MODE |
+ * +------+------+------+------+--//---+--------+-------+-----+------+
+ *
+ */
+#define PSYCHO_GCSR_IMPL(csr)	((u_int)(((csr) >> 60) & 0xf))
+#define PSYCHO_GCSR_VERS(csr)	((u_int)(((csr) >> 56) & 0xf))
+#define PSYCHO_GCSR_MID(csr)	((u_int)(((csr) >> 51) & 0x1f))
+#define PSYCHO_GCSR_IGN(csr)	((u_int)(((csr) >> 46) & 0x1f))
+#define PSYCHO_CSR_APCKEN	8	/* UPA addr parity check enable */
+#define PSYCHO_CSR_APERR	4	/* UPA addr parity error */
+#define PSYCHO_CSR_IAP		2	/* invert UPA address parity */
+#define PSYCHO_CSR_MODE		1	/* UPA/PCI handshake */
+
+/* Offsets into the PSR_PCICTL* register block */
+#define	PCR_CS			0x0000	/* PCI control/status register */
+#define	PCR_AFS			0x0010	/* PCI AFSR register */
+#define	PCR_AFA			0x0018	/* PCI AFAR register */
+#define	PCR_DIAG		0x0020	/* PCI diagnostic register */
+#define	PCR_TAS			0x0028	/* PCI target address space reg (IIi) */
+#define	PCR_STRBUF		0x0800	/* IOMMU streaming buffer registers. */
+
+/* INO defines */
+#define	PSYCHO_MAX_INO		0x3f
+
+/* Device space defines */
+#define	PSYCHO_CONF_SIZE	0x1000000
+#define	PSYCHO_CONF_BUS_SHIFT	16
+#define	PSYCHO_CONF_DEV_SHIFT	11
+#define	PSYCHO_CONF_FUNC_SHIFT	8
+#define	PSYCHO_CONF_REG_SHIFT	0
+#define	PSYCHO_IO_SIZE		0x1000000
+#define	PSYCHO_MEM_SIZE		0x100000000
+
+#define	PSYCHO_CONF_OFF(bus, slot, func, reg)				\
+	(((bus) << PSYCHO_CONF_BUS_SHIFT) |				\
+	((slot) << PSYCHO_CONF_DEV_SHIFT) |				\
+	((func) << PSYCHO_CONF_FUNC_SHIFT) |				\
+	((reg) << PSYCHO_CONF_REG_SHIFT))
+
+/* what the bits mean! */
+
+/*
+ * PCI [a|b] control/status register
+ * Note that the Hummingbird/Sabre only has one set of PCI control/status
+ * registers.
+ */
+#define	PCICTL_SBHERR	0x0000000800000000	/* strm. byte hole error; W1C */
+#define	PCICTL_SERR	0x0000000400000000	/* SERR asserted; W1C */
+#define	PCICTL_PCISPEED	0x0000000200000000	/* 0:half 1:full bus speed */
+#define	PCICTL_ARB_PARK	0x0000000000200000	/* PCI arbitration parking */
+#define	PCICTL_SBHINTEN	0x0000000000000400	/* strm. byte hole int. en. */
+#define	PCICTL_WAKEUPEN	0x0000000000000200	/* power mgmt. wakeup enable */
+#define	PCICTL_ERRINTEN	0x0000000000000100	/* PCI error interrupt enable */
+#define	PCICTL_ARB_4	0x000000000000000f	/* DVMA arb. 4 PCI slots mask */
+#define	PCICTL_ARB_6	0x000000000000003f	/* DVMA arb. 6 PCI slots mask */
+/* The following are Hummingbird/Sabre only. */
+#define	PCICTL_MRLM	0x0000001000000000	/* Memory Read Line/Multiple */
+#define	PCICTL_CPU_PRIO	0x0000000000100000	/* CPU extra arb. prio. en. */
+#define	PCICTL_ARB_PRIO	0x00000000000f0000	/* PCI extra arb. prio. en. */
+#define	PCICTL_RTRYWAIT 0x0000000000000080	/* 0:wait 1:retry DMA write */
+
+/* Uncorrectable error asynchronous fault status register */
+#define	UEAFSR_BLK	(1UL << 23)	/* Error caused by block transaction */
+#define	UEAFSR_P_DTE	(1UL << 56)	/* Pri. DVMA translation error */
+#define	UEAFSR_S_DTE	(1UL << 57)	/* Sec. DVMA translation error */
+#define	UEAFSR_S_DWR	(1UL << 58)	/* Sec. error during DVMA write */
+#define	UEAFSR_S_DRD	(1UL << 59)	/* Sec. error during DVMA read */
+#define	UEAFSR_S_PIO	(1UL << 60)	/* Sec. error during PIO access */
+#define	UEAFSR_P_DWR	(1UL << 61)	/* Pri. error during DVMA write */
+#define	UEAFSR_P_DRD	(1UL << 62)	/* Pri. error during DVMA read */
+#define	UEAFSR_P_PIO	(1UL << 63)	/* Pri. error during PIO access */
+
+/* Correctable error asynchronous fault status register */
+#define	CEAFSR_BLK	(1UL << 23)	/* Error caused by block transaction */
+#define	CEAFSR_S_DWR	(1UL << 58)	/* Sec. error caused by DVMA write */
+#define	CEAFSR_S_DRD	(1UL << 59)	/* Sec. error caused by DVMA read */
+#define	CEAFSR_S_PIO	(1UL << 60)	/* Sec. error caused by PIO access */
+#define	CEAFSR_P_DWR	(1UL << 61)	/* Pri. error caused by DVMA write */
+#define	CEAFSR_P_DRD	(1UL << 62)	/* Pri. error caused by DVMA read */
+#define	CEAFSR_P_PIO	(1UL << 63)	/* Pri. error caused by PIO access */
+
+/* PCI asynchronous fault status register */
+#define	PCIAFSR_P_MA	(1UL << 63)	/* Pri. master abort */
+#define	PCIAFSR_P_TA	(1UL << 62)	/* Pri. target abort */
+#define	PCIAFSR_P_RTRY	(1UL << 61)	/* Pri. excessive retries */
+#define	PCIAFSR_P_RERR	(1UL << 60)	/* Pri. parity error */
+#define	PCIAFSR_S_MA	(1UL << 59)	/* Sec. master abort */
+#define	PCIAFSR_S_TA	(1UL << 58)	/* Sec. target abort */
+#define	PCIAFSR_S_RTRY	(1UL << 57)	/* Sec. excessive retries */
+#define	PCIAFSR_S_RERR	(1UL << 56)	/* Sec. parity error */
+#define	PCIAFSR_BMASK	(0xffffUL << 32)/* Bytemask of failed pri. transfer */
+#define	PCIAFSR_BLK	(1UL << 31)	/* failed pri. transfer was block r/w */
+#define	PCIAFSR_MID	(0x3eUL << 25)	/* UPA MID causing error transaction */
+
+/* PCI diagnostic register */
+#define	DIAG_RTRY_DIS	0x0000000000000040	/* dis. retry limit */
+#define	DIAG_ISYNC_DIS	0x0000000000000020	/* dis. DMA write / int sync */
+#define	DIAG_DWSYNC_DIS	0x0000000000000010	/* dis. DMA write / PIO sync */
+
+/* Definitions for the target address space register */
+#define	PCITAS_ADDR_SHIFT	29
+
+/* Definitions for the Psycho configuration space */
+#define	PCS_DEVICE	0		/* Device number of Psycho CS entry */
+#define	PCS_FUNC	0		/* Function number of Psycho CS entry */
+
+/* Non-Standard registers in the configration space */
+#define	PCSR_SECBUS	0x40		/* Secondary bus number register */
+#define	PCSR_SUBBUS	0x41		/* Subordinate bus number register */
+
+/* Width of the physical addresses the IOMMU translates to */
+#define	PSYCHO_IOMMU_BITS	41
+#define	SABRE_IOMMU_BITS	34
+
+#endif /* !_SPARC64_PCI_PSYCHOREG_H_ */


Property changes on: trunk/sys/sparc64/pci/psychoreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/psychovar.h
===================================================================
--- trunk/sys/sparc64/pci/psychovar.h	                        (rev 0)
+++ trunk/sys/sparc64/pci/psychovar.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,74 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * 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 ``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.
+ *
+ *	from: NetBSD: psychovar.h,v 1.15 2008/05/29 14:51:26 mrg Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/pci/psychovar.h 292789 2015-12-27 19:37:47Z marius $
+ */
+
+#ifndef _SPARC64_PCI_PSYCHOVAR_H_
+#define _SPARC64_PCI_PSYCHOVAR_H_
+
+/*
+ * Per-PCI bus on mainbus softc structure; one for sabre, or two
+ * per pair of psychos.
+ */
+struct psycho_softc {
+	/*
+	 * This is here so that we can hook up the common bus interface
+	 * methods in ofw_pci.c directly.
+	 */
+	struct ofw_pci_softc		sc_ops;
+
+	struct iommu_state		*sc_is;
+	struct bus_dma_methods		*sc_dma_methods;
+
+	struct mtx			*sc_mtx;
+
+	struct resource			*sc_mem_res;
+	struct resource			*sc_irq_res[PSYCHO_NINTR];
+	void				*sc_ihand[PSYCHO_NINTR];
+
+	uint8_t				sc_pci_hpbcfg[16];
+
+	SLIST_ENTRY(psycho_softc)	sc_link;
+
+	device_t			sc_dev;
+
+	bus_addr_t			sc_pcictl;
+
+	u_int				sc_mode;
+#define	PSYCHO_MODE_SABRE		0
+#define	PSYCHO_MODE_PSYCHO		1
+
+	/* Bus A or B of a psycho pair? */
+	u_int				sc_half;
+
+	/* Interrupt Group Number for this device */
+	uint32_t			sc_ign;
+};
+
+#endif /* !_SPARC64_PCI_PSYCHOVAR_H_ */


Property changes on: trunk/sys/sparc64/pci/psychovar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/sbbc.c
===================================================================
--- trunk/sys/sparc64/pci/sbbc.c	                        (rev 0)
+++ trunk/sys/sparc64/pci/sbbc.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,1111 @@
+/* $MidnightBSD$ */
+/*	$OpenBSD: sbbc.c,v 1.7 2009/11/09 17:53:39 nicm Exp $	*/
+/*-
+ * Copyright (c) 2008 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*-
+ * Copyright (c) 2010 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/pci/sbbc.c 248965 2013-04-01 00:44:20Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/clock.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_bus.h>
+
+#include "clock_if.h"
+#include "uart_if.h"
+
+#define	SBBC_PCI_BAR		PCIR_BAR(0)
+#define	SBBC_PCI_VENDOR		0x108e
+#define	SBBC_PCI_PRODUCT	0xc416
+
+#define	SBBC_REGS_OFFSET	0x800000
+#define	SBBC_REGS_SIZE		0x6230
+#define	SBBC_EPLD_OFFSET	0x8e0000
+#define	SBBC_EPLD_SIZE		0x20
+#define	SBBC_SRAM_OFFSET	0x900000
+#define	SBBC_SRAM_SIZE		0x20000	/* 128KB SRAM */
+
+#define	SBBC_PCI_INT_STATUS	0x2320
+#define	SBBC_PCI_INT_ENABLE	0x2330
+#define	SBBC_PCI_ENABLE_INT_A	0x11
+
+#define	SBBC_EPLD_INTERRUPT	0x13
+#define	SBBC_EPLD_INTERRUPT_ON	0x01
+
+#define	SBBC_SRAM_CONS_IN		0x00000001
+#define	SBBC_SRAM_CONS_OUT		0x00000002
+#define	SBBC_SRAM_CONS_BRK		0x00000004
+#define	SBBC_SRAM_CONS_SPACE_IN		0x00000008
+#define	SBBC_SRAM_CONS_SPACE_OUT	0x00000010
+
+#define	SBBC_TAG_KEY_SIZE	8
+#define	SBBC_TAG_KEY_SCSOLIE	"SCSOLIE"	/* SC -> OS int. enable */
+#define	SBBC_TAG_KEY_SCSOLIR	"SCSOLIR"	/* SC -> OS int. reason */
+#define	SBBC_TAG_KEY_SOLCONS	"SOLCONS"	/* OS console buffer */
+#define	SBBC_TAG_KEY_SOLSCIE	"SOLSCIE"	/* OS -> SC int. enable */
+#define	SBBC_TAG_KEY_SOLSCIR	"SOLSCIR"	/* OS -> SC int. reason */
+#define	SBBC_TAG_KEY_TODDATA	"TODDATA"	/* OS TOD struct */
+#define	SBBC_TAG_OFF(x)		offsetof(struct sbbc_sram_tag, x)
+
+struct sbbc_sram_tag {
+	char		tag_key[SBBC_TAG_KEY_SIZE];
+	uint32_t	tag_size;
+	uint32_t	tag_offset;
+} __packed;
+
+#define	SBBC_TOC_MAGIC		"TOCSRAM"
+#define	SBBC_TOC_MAGIC_SIZE	8
+#define	SBBC_TOC_TAGS_MAX	32
+#define	SBBC_TOC_OFF(x)		offsetof(struct sbbc_sram_toc, x)
+
+struct sbbc_sram_toc {
+	char			toc_magic[SBBC_TOC_MAGIC_SIZE];
+	uint8_t			toc_reserved;
+	uint8_t			toc_type;
+	uint16_t		toc_version;
+	uint32_t		toc_ntags;
+	struct sbbc_sram_tag	toc_tag[SBBC_TOC_TAGS_MAX];
+} __packed;
+
+#define	SBBC_TOD_MAGIC		0x54443100	/* "TD1" */
+#define	SBBC_TOD_VERSION	1
+#define	SBBC_TOD_OFF(x)		offsetof(struct sbbc_sram_tod, x)
+
+struct sbbc_sram_tod {
+	uint32_t	tod_magic;
+	uint32_t	tod_version;
+	uint64_t	tod_time;
+	uint64_t	tod_skew;
+	uint32_t	tod_reserved;
+	uint32_t	tod_heartbeat;
+	uint32_t	tod_timeout;
+} __packed;
+
+#define	SBBC_CONS_MAGIC		0x434f4e00	/* "CON" */
+#define	SBBC_CONS_VERSION	1
+#define	SBBC_CONS_OFF(x)	offsetof(struct sbbc_sram_cons, x)
+
+struct sbbc_sram_cons {
+	uint32_t cons_magic;
+	uint32_t cons_version;
+	uint32_t cons_size;
+
+	uint32_t cons_in_begin;
+	uint32_t cons_in_end;
+	uint32_t cons_in_rdptr;
+	uint32_t cons_in_wrptr;
+
+	uint32_t cons_out_begin;
+	uint32_t cons_out_end;
+	uint32_t cons_out_rdptr;
+	uint32_t cons_out_wrptr;
+} __packed;
+
+struct sbbc_softc {
+	struct resource *sc_res;
+};
+
+#define	SBBC_READ_N(wdth, offs)						\
+	bus_space_read_ ## wdth((bst), (bsh), (offs))
+#define	SBBC_WRITE_N(wdth, offs, val)					\
+	bus_space_write_ ## wdth((bst), (bsh), (offs), (val))
+
+#define	SBBC_READ_1(offs)						\
+	SBBC_READ_N(1, (offs))
+#define	SBBC_READ_2(offs)						\
+	bswap16(SBBC_READ_N(2, (offs)))
+#define	SBBC_READ_4(offs)						\
+	bswap32(SBBC_READ_N(4, (offs)))
+#define	SBBC_READ_8(offs)						\
+	bswap64(SBBC_READ_N(8, (offs)))
+#define	SBBC_WRITE_1(offs, val)						\
+	SBBC_WRITE_N(1, (offs), (val))
+#define	SBBC_WRITE_2(offs, val)						\
+	SBBC_WRITE_N(2, (offs), bswap16(val))
+#define	SBBC_WRITE_4(offs, val)						\
+	SBBC_WRITE_N(4, (offs), bswap32(val))
+#define	SBBC_WRITE_8(offs, val)						\
+	SBBC_WRITE_N(8, (offs), bswap64(val))
+
+#define	SBBC_REGS_READ_1(offs)						\
+	SBBC_READ_1((offs) + SBBC_REGS_OFFSET)
+#define	SBBC_REGS_READ_2(offs)						\
+	SBBC_READ_2((offs) + SBBC_REGS_OFFSET)
+#define	SBBC_REGS_READ_4(offs)						\
+	SBBC_READ_4((offs) + SBBC_REGS_OFFSET)
+#define	SBBC_REGS_READ_8(offs)						\
+	SBBC_READ_8((offs) + SBBC_REGS_OFFSET)
+#define	SBBC_REGS_WRITE_1(offs, val)					\
+	SBBC_WRITE_1((offs) + SBBC_REGS_OFFSET, (val))
+#define	SBBC_REGS_WRITE_2(offs, val)					\
+	SBBC_WRITE_2((offs) + SBBC_REGS_OFFSET, (val))
+#define	SBBC_REGS_WRITE_4(offs, val)					\
+	SBBC_WRITE_4((offs) + SBBC_REGS_OFFSET, (val))
+#define	SBBC_REGS_WRITE_8(offs, val)					\
+	SBBC_WRITE_8((offs) + SBBC_REGS_OFFSET, (val))
+
+#define	SBBC_EPLD_READ_1(offs)						\
+	SBBC_READ_1((offs) + SBBC_EPLD_OFFSET)
+#define	SBBC_EPLD_READ_2(offs)						\
+	SBBC_READ_2((offs) + SBBC_EPLD_OFFSET)
+#define	SBBC_EPLD_READ_4(offs)						\
+	SBBC_READ_4((offs) + SBBC_EPLD_OFFSET)
+#define	SBBC_EPLD_READ_8(offs)						\
+	SBBC_READ_8((offs) + SBBC_EPLD_OFFSET)
+#define	SBBC_EPLD_WRITE_1(offs, val)					\
+	SBBC_WRITE_1((offs) + SBBC_EPLD_OFFSET, (val))
+#define	SBBC_EPLD_WRITE_2(offs, val)					\
+	SBBC_WRITE_2((offs) + SBBC_EPLD_OFFSET, (val))
+#define	SBBC_EPLD_WRITE_4(offs, val)					\
+	SBBC_WRITE_4((offs) + SBBC_EPLD_OFFSET, (val))
+#define	SBBC_EPLD_WRITE_8(offs, val)					\
+	SBBC_WRITE_8((offs) + SBBC_EPLD_OFFSET, (val))
+
+#define	SBBC_SRAM_READ_1(offs)						\
+	SBBC_READ_1((offs) + SBBC_SRAM_OFFSET)
+#define	SBBC_SRAM_READ_2(offs)						\
+	SBBC_READ_2((offs) + SBBC_SRAM_OFFSET)
+#define	SBBC_SRAM_READ_4(offs)						\
+	SBBC_READ_4((offs) + SBBC_SRAM_OFFSET)
+#define	SBBC_SRAM_READ_8(offs)						\
+	SBBC_READ_8((offs) + SBBC_SRAM_OFFSET)
+#define	SBBC_SRAM_WRITE_1(offs, val)					\
+	SBBC_WRITE_1((offs) + SBBC_SRAM_OFFSET, (val))
+#define	SBBC_SRAM_WRITE_2(offs, val)					\
+	SBBC_WRITE_2((offs) + SBBC_SRAM_OFFSET, (val))
+#define	SBBC_SRAM_WRITE_4(offs, val)					\
+	SBBC_WRITE_4((offs) + SBBC_SRAM_OFFSET, (val))
+#define	SBBC_SRAM_WRITE_8(offs, val)					\
+	SBBC_WRITE_8((offs) + SBBC_SRAM_OFFSET, (val))
+
+#define	SUNW_SETCONSINPUT	"SUNW,set-console-input"
+#define	SUNW_SETCONSINPUT_CLNT	"CON_CLNT"
+#define	SUNW_SETCONSINPUT_OBP	"CON_OBP"
+
+static u_int sbbc_console;
+
+static uint32_t	sbbc_scsolie;
+static uint32_t	sbbc_scsolir;
+static uint32_t	sbbc_solcons;
+static uint32_t	sbbc_solscie;
+static uint32_t	sbbc_solscir;
+static uint32_t	sbbc_toddata;
+
+/*
+ * internal helpers
+ */
+static int sbbc_parse_toc(bus_space_tag_t bst, bus_space_handle_t bsh);
+static inline void sbbc_send_intr(bus_space_tag_t bst,
+    bus_space_handle_t bsh);
+static const char *sbbc_serengeti_set_console_input(char *new);
+
+/*
+ * SBBC PCI interface
+ */
+static bus_activate_resource_t sbbc_bus_activate_resource;
+static bus_adjust_resource_t sbbc_bus_adjust_resource;
+static bus_deactivate_resource_t sbbc_bus_deactivate_resource;
+static bus_alloc_resource_t sbbc_bus_alloc_resource;
+static bus_release_resource_t sbbc_bus_release_resource;
+static bus_get_resource_list_t sbbc_bus_get_resource_list;
+static bus_setup_intr_t sbbc_bus_setup_intr;
+static bus_teardown_intr_t sbbc_bus_teardown_intr;
+
+static device_attach_t sbbc_pci_attach;
+static device_probe_t sbbc_pci_probe;
+
+static clock_gettime_t sbbc_tod_gettime;
+static clock_settime_t sbbc_tod_settime;
+
+static device_method_t sbbc_pci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		sbbc_pci_probe),
+	DEVMETHOD(device_attach,	sbbc_pci_attach),
+
+	DEVMETHOD(bus_alloc_resource,	sbbc_bus_alloc_resource),
+	DEVMETHOD(bus_activate_resource,sbbc_bus_activate_resource),
+	DEVMETHOD(bus_deactivate_resource,sbbc_bus_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	sbbc_bus_adjust_resource),
+	DEVMETHOD(bus_release_resource,	sbbc_bus_release_resource),
+	DEVMETHOD(bus_setup_intr,	sbbc_bus_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	sbbc_bus_teardown_intr),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	DEVMETHOD(bus_get_resource_list, sbbc_bus_get_resource_list),
+
+	/* clock interface */
+	DEVMETHOD(clock_gettime,	sbbc_tod_gettime),
+	DEVMETHOD(clock_settime,	sbbc_tod_settime),
+
+	DEVMETHOD_END
+};
+
+static devclass_t sbbc_devclass;
+
+DEFINE_CLASS_0(sbbc, sbbc_driver, sbbc_pci_methods, sizeof(struct sbbc_softc));
+DRIVER_MODULE(sbbc, pci, sbbc_driver, sbbc_devclass, NULL, NULL);
+
+static int
+sbbc_pci_probe(device_t dev)
+{
+
+	if (pci_get_vendor(dev) == SBBC_PCI_VENDOR &&
+	    pci_get_device(dev) == SBBC_PCI_PRODUCT) {
+		device_set_desc(dev, "Sun BootBus controller");
+		return (BUS_PROBE_DEFAULT);
+	}
+	return (ENXIO);
+}
+
+static int
+sbbc_pci_attach(device_t dev)
+{
+	struct sbbc_softc *sc;
+	struct timespec ts;
+	device_t child;
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+	phandle_t node;
+	int error, rid;
+	uint32_t val;
+
+	/* Nothing to to if we're not the chosen one. */
+	if ((node = OF_finddevice("/chosen")) == -1) {
+		device_printf(dev, "failed to find /chosen\n");
+		return (ENXIO);
+	}
+	if (OF_getprop(node, "iosram", &node, sizeof(node)) == -1) {
+		device_printf(dev, "failed to get iosram\n");
+		return (ENXIO);
+	}
+	if (node != ofw_bus_get_node(dev))
+		return (0);
+
+	sc = device_get_softc(dev);
+	rid = SBBC_PCI_BAR;
+	sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->sc_res == NULL) {
+		device_printf(dev, "failed to allocate resources\n");
+		return (ENXIO);
+	}
+	bst = rman_get_bustag(sc->sc_res);
+	bsh = rman_get_bushandle(sc->sc_res);
+	if (sbbc_console != 0) {
+		/* Once again the interrupt pin isn't set. */
+		if (pci_get_intpin(dev) == 0)
+			pci_set_intpin(dev, 1);
+		child = device_add_child(dev, NULL, -1);
+		if (child == NULL)
+			device_printf(dev, "failed to add UART device\n");
+		error = bus_generic_attach(dev);
+		if (error != 0)
+			device_printf(dev, "failed to attach UART device\n");
+	} else {
+		error = sbbc_parse_toc(bst, bsh);
+		if (error != 0) {
+			device_printf(dev, "failed to parse TOC\n");
+			if (sbbc_console != 0) {
+				bus_release_resource(dev, SYS_RES_MEMORY, rid,
+				    sc->sc_res);
+				return (error);
+			}
+		}
+	}
+	if (sbbc_toddata != 0) {
+		if ((val = SBBC_SRAM_READ_4(sbbc_toddata +
+		    SBBC_TOD_OFF(tod_magic))) != SBBC_TOD_MAGIC)
+			device_printf(dev, "invalid TOD magic %#x\n", val);
+		else if ((val = SBBC_SRAM_READ_4(sbbc_toddata +
+		    SBBC_TOD_OFF(tod_version))) < SBBC_TOD_VERSION)
+			device_printf(dev, "invalid TOD version %#x\n", val);
+		else {
+			clock_register(dev, 1000000); /* 1 sec. resolution */
+			if (bootverbose) {
+				sbbc_tod_gettime(dev, &ts);
+				device_printf(dev,
+				    "current time: %ld.%09ld\n",
+				    (long)ts.tv_sec, ts.tv_nsec);
+			}
+		}
+	}
+	return (0);
+}
+
+/*
+ * Note that the bus methods don't pass-through the uart(4) requests but act
+ * as if they would come from sbbc(4) in order to avoid complications with
+ * pci(4) (actually, uart(4) isn't a real child but rather a function of
+ * sbbc(4) anyway).
+ */
+
+static struct resource *
+sbbc_bus_alloc_resource(device_t dev, device_t child __unused, int type,
+    int *rid, u_long start, u_long end, u_long count, u_int flags)
+{
+	struct sbbc_softc *sc;
+
+	sc = device_get_softc(dev);
+	switch (type) {
+	case SYS_RES_IRQ:
+		return (bus_generic_alloc_resource(dev, dev, type, rid, start,
+		    end, count, flags));
+	case SYS_RES_MEMORY:
+		return (sc->sc_res);
+	default:
+		return (NULL);
+	}
+}
+
+static int
+sbbc_bus_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *res)
+{
+
+	if (type == SYS_RES_MEMORY)
+		return (0);
+	return (bus_generic_activate_resource(bus, child, type, rid, res));
+}
+
+static int
+sbbc_bus_deactivate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *res)
+{
+
+	if (type == SYS_RES_MEMORY)
+		return (0);
+	return (bus_generic_deactivate_resource(bus, child, type, rid, res));
+}
+
+static int
+sbbc_bus_adjust_resource(device_t bus __unused, device_t child __unused,
+    int type __unused, struct resource *res __unused, u_long start __unused,
+    u_long end __unused)
+{
+
+	return (ENXIO);
+}
+
+static int
+sbbc_bus_release_resource(device_t dev, device_t child __unused, int type,
+    int rid, struct resource *res)
+{
+
+	if (type == SYS_RES_IRQ)
+		return (bus_generic_release_resource(dev, dev, type, rid,
+		    res));
+	return (0);
+}
+
+static struct resource_list *
+sbbc_bus_get_resource_list(device_t dev, device_t child __unused)
+{
+
+	return (bus_generic_get_resource_list(dev, dev));
+}
+
+static int
+sbbc_bus_setup_intr(device_t dev, device_t child __unused,
+    struct resource *res, int flags, driver_filter_t *filt,
+    driver_intr_t *intr, void *arg, void **cookiep)
+{
+
+	return (bus_generic_setup_intr(dev, dev, res, flags, filt, intr, arg,
+	    cookiep));
+}
+
+static int
+sbbc_bus_teardown_intr(device_t dev, device_t child __unused,
+    struct resource *res, void *cookie)
+{
+
+	return (bus_generic_teardown_intr(dev, dev, res, cookie));
+}
+
+/*
+ * internal helpers
+ */
+static int
+sbbc_parse_toc(bus_space_tag_t bst, bus_space_handle_t bsh)
+{
+	char buf[MAX(SBBC_TAG_KEY_SIZE, SBBC_TOC_MAGIC_SIZE)];
+	bus_size_t tag;
+	phandle_t node;
+	uint32_t off, sram_toc;
+	u_int i, tags;
+
+	if ((node = OF_finddevice("/chosen")) == -1)
+		return (ENXIO);
+	/* SRAM TOC offset defaults to 0. */
+	if (OF_getprop(node, "iosram-toc", &sram_toc, sizeof(sram_toc)) <= 0)
+		sram_toc = 0;
+
+	bus_space_read_region_1(bst, bsh, SBBC_SRAM_OFFSET + sram_toc +
+	    SBBC_TOC_OFF(toc_magic), buf, SBBC_TOC_MAGIC_SIZE);
+	buf[SBBC_TOC_MAGIC_SIZE - 1] = '\0';
+	if (strcmp(buf, SBBC_TOC_MAGIC) != 0)
+		return (ENXIO);
+
+	tags = SBBC_SRAM_READ_4(sram_toc + SBBC_TOC_OFF(toc_ntags));
+	for (i = 0; i < tags; i++) {
+		tag = sram_toc + SBBC_TOC_OFF(toc_tag) +
+		    i * sizeof(struct sbbc_sram_tag);
+		bus_space_read_region_1(bst, bsh, SBBC_SRAM_OFFSET + tag +
+		    SBBC_TAG_OFF(tag_key), buf, SBBC_TAG_KEY_SIZE);
+		buf[SBBC_TAG_KEY_SIZE - 1] = '\0';
+		off = SBBC_SRAM_READ_4(tag + SBBC_TAG_OFF(tag_offset));
+		if (strcmp(buf, SBBC_TAG_KEY_SCSOLIE) == 0)
+			sbbc_scsolie = off;
+		else if (strcmp(buf, SBBC_TAG_KEY_SCSOLIR) == 0)
+			sbbc_scsolir = off;
+		else if (strcmp(buf, SBBC_TAG_KEY_SOLCONS) == 0)
+			sbbc_solcons = off;
+		else if (strcmp(buf, SBBC_TAG_KEY_SOLSCIE) == 0)
+			sbbc_solscie = off;
+		else if (strcmp(buf, SBBC_TAG_KEY_SOLSCIR) == 0)
+			sbbc_solscir = off;
+		else if (strcmp(buf, SBBC_TAG_KEY_TODDATA) == 0)
+			sbbc_toddata = off;
+	}
+	return (0);
+}
+
+static const char *
+sbbc_serengeti_set_console_input(char *new)
+{
+	struct {
+		cell_t name;
+		cell_t nargs;
+		cell_t nreturns;
+		cell_t new;
+		cell_t old;
+	} args = {
+		(cell_t)SUNW_SETCONSINPUT,
+		1,
+		1,
+	};
+
+	args.new = (cell_t)new;
+	if (ofw_entry(&args) == -1)
+		return (NULL);
+	return ((const char *)args.old);
+}
+
+static inline void
+sbbc_send_intr(bus_space_tag_t bst, bus_space_handle_t bsh)
+{
+
+	SBBC_EPLD_WRITE_1(SBBC_EPLD_INTERRUPT, SBBC_EPLD_INTERRUPT_ON);
+	bus_space_barrier(bst, bsh, SBBC_EPLD_OFFSET + SBBC_EPLD_INTERRUPT, 1,
+	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
+}
+
+/*
+ * TOD interface
+ */
+static int
+sbbc_tod_gettime(device_t dev, struct timespec *ts)
+{
+	struct sbbc_softc *sc;
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+
+	sc = device_get_softc(dev);
+	bst = rman_get_bustag(sc->sc_res);
+	bsh = rman_get_bushandle(sc->sc_res);
+
+	ts->tv_sec = SBBC_SRAM_READ_8(sbbc_toddata + SBBC_TOD_OFF(tod_time)) +
+	    SBBC_SRAM_READ_8(sbbc_toddata + SBBC_TOD_OFF(tod_skew));
+	ts->tv_nsec = 0;
+	return (0);
+}
+
+static int
+sbbc_tod_settime(device_t dev, struct timespec *ts)
+{
+	struct sbbc_softc *sc;
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+
+	sc = device_get_softc(dev);
+	bst = rman_get_bustag(sc->sc_res);
+	bsh = rman_get_bushandle(sc->sc_res);
+
+	SBBC_SRAM_WRITE_8(sbbc_toddata + SBBC_TOD_OFF(tod_skew), ts->tv_sec -
+	    SBBC_SRAM_READ_8(sbbc_toddata + SBBC_TOD_OFF(tod_time)));
+	return (0);
+}
+
+/*
+ * UART bus front-end
+ */
+static device_probe_t sbbc_uart_sbbc_probe;
+
+static device_method_t sbbc_uart_sbbc_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		sbbc_uart_sbbc_probe),
+	DEVMETHOD(device_attach,	uart_bus_attach),
+	DEVMETHOD(device_detach,	uart_bus_detach),
+
+	DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(uart, sbbc_uart_driver, sbbc_uart_sbbc_methods,
+    sizeof(struct uart_softc));
+DRIVER_MODULE(uart, sbbc, sbbc_uart_driver, uart_devclass, NULL, NULL);
+
+static int
+sbbc_uart_sbbc_probe(device_t dev)
+{
+	struct uart_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_class = &uart_sbbc_class;
+	device_set_desc(dev, "Serengeti console");
+	return (uart_bus_probe(dev, 0, 0, SBBC_PCI_BAR, 0));
+}
+
+/*
+ * Low-level UART interface
+ */
+static int sbbc_uart_probe(struct uart_bas *bas);
+static void sbbc_uart_init(struct uart_bas *bas, int baudrate, int databits,
+    int stopbits, int parity);
+static void sbbc_uart_term(struct uart_bas *bas);
+static void sbbc_uart_putc(struct uart_bas *bas, int c);
+static int sbbc_uart_rxready(struct uart_bas *bas);
+static int sbbc_uart_getc(struct uart_bas *bas, struct mtx *hwmtx);
+
+static struct uart_ops sbbc_uart_ops = {
+	.probe = sbbc_uart_probe,
+	.init = sbbc_uart_init,
+	.term = sbbc_uart_term,
+	.putc = sbbc_uart_putc,
+	.rxready = sbbc_uart_rxready,
+	.getc = sbbc_uart_getc,
+};
+
+static int
+sbbc_uart_probe(struct uart_bas *bas)
+{
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+	int error;
+
+	sbbc_console = 1;
+	bst = bas->bst;
+	bsh = bas->bsh;
+	error = sbbc_parse_toc(bst, bsh);
+	if (error != 0)
+		return (error);
+
+	if (sbbc_scsolie == 0 || sbbc_scsolir == 0 || sbbc_solcons == 0 ||
+	    sbbc_solscie == 0 || sbbc_solscir == 0)
+		return (ENXIO);
+
+	if (SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_magic)) !=
+	    SBBC_CONS_MAGIC || SBBC_SRAM_READ_4(sbbc_solcons +
+	    SBBC_CONS_OFF(cons_version)) < SBBC_CONS_VERSION)
+		return (ENXIO);
+	return (0);
+}
+
+static void
+sbbc_uart_init(struct uart_bas *bas, int baudrate __unused,
+    int databits __unused, int stopbits __unused, int parity __unused)
+{
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+
+	bst = bas->bst;
+	bsh = bas->bsh;
+
+	/* Enable output to and space in from the SC interrupts. */
+	SBBC_SRAM_WRITE_4(sbbc_solscie, SBBC_SRAM_READ_4(sbbc_solscie) |
+	    SBBC_SRAM_CONS_OUT | SBBC_SRAM_CONS_SPACE_IN);
+	uart_barrier(bas);
+
+	/* Take over the console input. */
+	sbbc_serengeti_set_console_input(SUNW_SETCONSINPUT_CLNT);
+}
+
+static void
+sbbc_uart_term(struct uart_bas *bas __unused)
+{
+
+	/* Give back the console input. */
+	sbbc_serengeti_set_console_input(SUNW_SETCONSINPUT_OBP);
+}
+
+static void
+sbbc_uart_putc(struct uart_bas *bas, int c)
+{
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+	uint32_t wrptr;
+
+	bst = bas->bst;
+	bsh = bas->bsh;
+
+	wrptr = SBBC_SRAM_READ_4(sbbc_solcons +
+	    SBBC_CONS_OFF(cons_out_wrptr));
+	SBBC_SRAM_WRITE_1(sbbc_solcons + wrptr, c);
+	uart_barrier(bas);
+	if (++wrptr == SBBC_SRAM_READ_4(sbbc_solcons +
+	    SBBC_CONS_OFF(cons_out_end)))
+		wrptr = SBBC_SRAM_READ_4(sbbc_solcons +
+		    SBBC_CONS_OFF(cons_out_begin));
+	SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_wrptr),
+	    wrptr);
+	uart_barrier(bas);
+
+	SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) |
+	    SBBC_SRAM_CONS_OUT);
+	uart_barrier(bas);
+	sbbc_send_intr(bst, bsh);
+}
+
+static int
+sbbc_uart_rxready(struct uart_bas *bas)
+{
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+
+	bst = bas->bst;
+	bsh = bas->bsh;
+
+	if (SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr)) ==
+	    SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_wrptr)))
+		return (0);
+	return (1);
+}
+
+static int
+sbbc_uart_getc(struct uart_bas *bas, struct mtx *hwmtx)
+{
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+	int c;
+	uint32_t rdptr;
+
+	bst = bas->bst;
+	bsh = bas->bsh;
+
+	uart_lock(hwmtx);
+
+	while (sbbc_uart_rxready(bas) == 0) {
+		uart_unlock(hwmtx);
+		DELAY(4);
+		uart_lock(hwmtx);
+	}
+
+	rdptr = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr));
+	c = SBBC_SRAM_READ_1(sbbc_solcons + rdptr);
+	uart_barrier(bas);
+	if (++rdptr == SBBC_SRAM_READ_4(sbbc_solcons +
+	    SBBC_CONS_OFF(cons_in_end)))
+		rdptr = SBBC_SRAM_READ_4(sbbc_solcons +
+		    SBBC_CONS_OFF(cons_in_begin));
+	SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr),
+	    rdptr);
+	uart_barrier(bas);
+	SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) |
+	    SBBC_SRAM_CONS_SPACE_IN);
+	uart_barrier(bas);
+	sbbc_send_intr(bst, bsh);
+
+	uart_unlock(hwmtx);
+	return (c);
+}
+
+/*
+ * High-level UART interface
+ */
+static int sbbc_uart_bus_attach(struct uart_softc *sc);
+static int sbbc_uart_bus_detach(struct uart_softc *sc);
+static int sbbc_uart_bus_flush(struct uart_softc *sc, int what);
+static int sbbc_uart_bus_getsig(struct uart_softc *sc);
+static int sbbc_uart_bus_ioctl(struct uart_softc *sc, int request,
+    intptr_t data);
+static int sbbc_uart_bus_ipend(struct uart_softc *sc);
+static int sbbc_uart_bus_param(struct uart_softc *sc, int baudrate,
+    int databits, int stopbits, int parity);
+static int sbbc_uart_bus_probe(struct uart_softc *sc);
+static int sbbc_uart_bus_receive(struct uart_softc *sc);
+static int sbbc_uart_bus_setsig(struct uart_softc *sc, int sig);
+static int sbbc_uart_bus_transmit(struct uart_softc *sc);
+
+static kobj_method_t sbbc_uart_methods[] = {
+	KOBJMETHOD(uart_attach,		sbbc_uart_bus_attach),
+	KOBJMETHOD(uart_detach,		sbbc_uart_bus_detach),
+	KOBJMETHOD(uart_flush,		sbbc_uart_bus_flush),
+	KOBJMETHOD(uart_getsig,		sbbc_uart_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		sbbc_uart_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		sbbc_uart_bus_ipend),
+	KOBJMETHOD(uart_param,		sbbc_uart_bus_param),
+	KOBJMETHOD(uart_probe,		sbbc_uart_bus_probe),
+	KOBJMETHOD(uart_receive,	sbbc_uart_bus_receive),
+	KOBJMETHOD(uart_setsig,		sbbc_uart_bus_setsig),
+	KOBJMETHOD(uart_transmit,	sbbc_uart_bus_transmit),
+
+	DEVMETHOD_END
+};
+
+struct uart_class uart_sbbc_class = {
+	"sbbc",
+	sbbc_uart_methods,
+	sizeof(struct uart_softc),
+	.uc_ops = &sbbc_uart_ops,
+	.uc_range = 1,
+	.uc_rclk = 0x5bbc	/* arbitrary */
+};
+
+#define	SIGCHG(c, i, s, d)						\
+	if ((c) != 0) {							\
+		i |= (((i) & (s)) != 0) ? (s) : (s) | (d);		\
+	} else {							\
+		i = (((i) & (s)) != 0) ? ((i) & ~(s)) | (d) : (i);	\
+	}
+
+static int
+sbbc_uart_bus_attach(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+	uint32_t wrptr;
+
+	bas = &sc->sc_bas;
+	bst = bas->bst;
+	bsh = bas->bsh;
+
+	uart_lock(sc->sc_hwmtx);
+
+	/*
+	 * Let the current output drain before enabling interrupts.  Not
+	 * doing so tends to cause lost output when turning them on.
+	 */
+	wrptr = SBBC_SRAM_READ_4(sbbc_solcons +
+	    SBBC_CONS_OFF(cons_out_wrptr));
+	while (SBBC_SRAM_READ_4(sbbc_solcons +
+	    SBBC_CONS_OFF(cons_out_rdptr)) != wrptr);
+		cpu_spinwait();
+
+	/* Clear and acknowledge possibly outstanding interrupts. */
+	SBBC_SRAM_WRITE_4(sbbc_scsolir, 0);
+	uart_barrier(bas);
+	SBBC_REGS_WRITE_4(SBBC_PCI_INT_STATUS,
+	    SBBC_SRAM_READ_4(sbbc_scsolir));
+	uart_barrier(bas);
+	/* Enable PCI interrupts. */
+	SBBC_REGS_WRITE_4(SBBC_PCI_INT_ENABLE, SBBC_PCI_ENABLE_INT_A);
+	uart_barrier(bas);
+	/* Enable input from and output to SC as well as break interrupts. */
+	SBBC_SRAM_WRITE_4(sbbc_scsolie, SBBC_SRAM_READ_4(sbbc_scsolie) |
+	    SBBC_SRAM_CONS_IN | SBBC_SRAM_CONS_BRK |
+	    SBBC_SRAM_CONS_SPACE_OUT);
+	uart_barrier(bas);
+
+	uart_unlock(sc->sc_hwmtx);
+	return (0);
+}
+
+static int
+sbbc_uart_bus_detach(struct uart_softc *sc)
+{
+
+	/* Give back the console input. */
+	sbbc_serengeti_set_console_input(SUNW_SETCONSINPUT_OBP);
+	return (0);
+}
+
+static int
+sbbc_uart_bus_flush(struct uart_softc *sc, int what)
+{
+	struct uart_bas *bas;
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+
+	bas = &sc->sc_bas;
+	bst = bas->bst;
+	bsh = bas->bsh;
+
+	if ((what & UART_FLUSH_TRANSMITTER) != 0)
+		return (ENODEV);
+	if ((what & UART_FLUSH_RECEIVER) != 0) {
+		SBBC_SRAM_WRITE_4(sbbc_solcons +
+		    SBBC_CONS_OFF(cons_in_rdptr),
+		    SBBC_SRAM_READ_4(sbbc_solcons +
+		    SBBC_CONS_OFF(cons_in_wrptr)));
+		uart_barrier(bas);
+	}
+	return (0);
+}
+
+static int
+sbbc_uart_bus_getsig(struct uart_softc *sc)
+{
+	uint32_t dummy, new, old, sig;
+
+	do {
+		old = sc->sc_hwsig;
+		sig = old;
+		dummy = 0;
+		SIGCHG(dummy, sig, SER_CTS, SER_DCTS);
+		SIGCHG(dummy, sig, SER_DCD, SER_DDCD);
+		SIGCHG(dummy, sig, SER_DSR, SER_DDSR);
+		new = sig & ~SER_MASK_DELTA;
+	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+	return (sig);
+}
+
+static int
+sbbc_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+	int error;
+
+	error = 0;
+	uart_lock(sc->sc_hwmtx);
+	switch (request) {
+	case UART_IOCTL_BAUD:
+		*(int*)data = 9600;	/* arbitrary */
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	uart_unlock(sc->sc_hwmtx);
+	return (error);
+}
+
+static int
+sbbc_uart_bus_ipend(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+	int ipend;
+	uint32_t reason, status;
+
+	bas = &sc->sc_bas;
+	bst = bas->bst;
+	bsh = bas->bsh;
+
+	uart_lock(sc->sc_hwmtx);
+	status = SBBC_REGS_READ_4(SBBC_PCI_INT_STATUS);
+	if (status == 0) {
+		uart_unlock(sc->sc_hwmtx);
+		return (0);
+	}
+
+	/*
+	 * Unfortunately, we can't use compare and swap for non-cachable
+	 * memory.
+	 */
+	reason = SBBC_SRAM_READ_4(sbbc_scsolir);
+	SBBC_SRAM_WRITE_4(sbbc_scsolir, 0);
+	uart_barrier(bas);
+	/* Acknowledge the interrupt. */
+	SBBC_REGS_WRITE_4(SBBC_PCI_INT_STATUS, status);
+	uart_barrier(bas);
+
+	uart_unlock(sc->sc_hwmtx);
+
+	ipend = 0;
+	if ((reason & SBBC_SRAM_CONS_IN) != 0)
+		ipend |= SER_INT_RXREADY;
+	if ((reason & SBBC_SRAM_CONS_BRK) != 0)
+		ipend |= SER_INT_BREAK;
+	if ((reason & SBBC_SRAM_CONS_SPACE_OUT) != 0 &&
+	    SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_rdptr)) ==
+	    SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_wrptr)))
+		ipend |= SER_INT_TXIDLE;
+	return (ipend);
+}
+
+static int
+sbbc_uart_bus_param(struct uart_softc *sc __unused, int baudrate __unused,
+    int databits __unused, int stopbits __unused, int parity __unused)
+{
+
+	return (0);
+}
+
+static int
+sbbc_uart_bus_probe(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+
+	if (sbbc_console != 0) {
+		bas = &sc->sc_bas;
+		bst = bas->bst;
+		bsh = bas->bsh;
+		sc->sc_rxfifosz = SBBC_SRAM_READ_4(sbbc_solcons +
+		    SBBC_CONS_OFF(cons_in_end)) - SBBC_SRAM_READ_4(sbbc_solcons +
+		    SBBC_CONS_OFF(cons_in_begin)) - 1;
+		sc->sc_txfifosz = SBBC_SRAM_READ_4(sbbc_solcons +
+		    SBBC_CONS_OFF(cons_out_end)) - SBBC_SRAM_READ_4(sbbc_solcons +
+		    SBBC_CONS_OFF(cons_out_begin)) - 1;
+		return (0);
+	}
+	return (ENXIO);
+}
+
+static int
+sbbc_uart_bus_receive(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+	int c;
+	uint32_t end, rdptr, wrptr;
+
+	bas = &sc->sc_bas;
+	bst = bas->bst;
+	bsh = bas->bsh;
+
+	uart_lock(sc->sc_hwmtx);
+
+	end = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_end));
+	rdptr = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr));
+	wrptr = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_wrptr));
+	while (rdptr != wrptr) {
+		if (uart_rx_full(sc) != 0) {
+			sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
+			break;
+		}
+		c = SBBC_SRAM_READ_1(sbbc_solcons + rdptr);
+		uart_rx_put(sc, c);
+		if (++rdptr == end)
+			rdptr = SBBC_SRAM_READ_4(sbbc_solcons +
+			    SBBC_CONS_OFF(cons_in_begin));
+	}
+	uart_barrier(bas);
+	SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr),
+	    rdptr);
+	uart_barrier(bas);
+	SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) |
+	    SBBC_SRAM_CONS_SPACE_IN);
+	uart_barrier(bas);
+	sbbc_send_intr(bst, bsh);
+
+	uart_unlock(sc->sc_hwmtx);
+	return (0);
+}
+
+static int
+sbbc_uart_bus_setsig(struct uart_softc *sc, int sig)
+{
+	struct uart_bas *bas;
+	uint32_t new, old;
+
+	bas = &sc->sc_bas;
+	do {
+		old = sc->sc_hwsig;
+		new = old;
+		if ((sig & SER_DDTR) != 0) {
+			SIGCHG(sig & SER_DTR, new, SER_DTR, SER_DDTR);
+		}
+		if ((sig & SER_DRTS) != 0) {
+			SIGCHG(sig & SER_RTS, new, SER_RTS, SER_DRTS);
+		}
+	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+	return (0);
+}
+
+static int
+sbbc_uart_bus_transmit(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+	int i;
+	uint32_t end, wrptr;
+
+	bas = &sc->sc_bas;
+	bst = bas->bst;
+	bsh = bas->bsh;
+
+	uart_lock(sc->sc_hwmtx);
+
+	end = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_end));
+	wrptr = SBBC_SRAM_READ_4(sbbc_solcons +
+	    SBBC_CONS_OFF(cons_out_wrptr));
+	for (i = 0; i < sc->sc_txdatasz; i++) {
+		SBBC_SRAM_WRITE_1(sbbc_solcons + wrptr, sc->sc_txbuf[i]);
+		if (++wrptr == end)
+			wrptr = SBBC_SRAM_READ_4(sbbc_solcons +
+			    SBBC_CONS_OFF(cons_out_begin));
+	}
+	uart_barrier(bas);
+	SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_wrptr),
+	    wrptr);
+	uart_barrier(bas);
+	SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) |
+	    SBBC_SRAM_CONS_OUT);
+	uart_barrier(bas);
+	sbbc_send_intr(bst, bsh);
+	sc->sc_txbusy = 1;
+
+	uart_unlock(sc->sc_hwmtx);
+	return (0);
+}


Property changes on: trunk/sys/sparc64/pci/sbbc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/schizo.c
===================================================================
--- trunk/sys/sparc64/pci/schizo.c	                        (rev 0)
+++ trunk/sys/sparc64/pci/schizo.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,1257 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm at FreeBSD.org>
+ * Copyright (c) 2005 - 2011 by Marius Strobl <marius at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp
+ *	from: FreeBSD: psycho.c 183152 2008-09-18 19:45:22Z marius
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/pci/schizo.c 292789 2015-12-27 19:37:47Z marius $");
+
+/*
+ * Driver for `Schizo' Fireplane/Safari to PCI 2.1, `Tomatillo' JBus to
+ * PCI 2.2 and `XMITS' Fireplane/Safari to PCI-X bridges
+ */
+
+#include "opt_ofw_pci.h"
+#include "opt_schizo.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/bus_common.h>
+#include <machine/bus_private.h>
+#include <machine/iommureg.h>
+#include <machine/iommuvar.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <sparc64/pci/ofw_pci.h>
+#include <sparc64/pci/schizoreg.h>
+#include <sparc64/pci/schizovar.h>
+
+#include "pcib_if.h"
+
+static const struct schizo_desc *schizo_get_desc(device_t);
+static void schizo_set_intr(struct schizo_softc *, u_int, u_int,
+    driver_filter_t);
+static void schizo_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map,
+    bus_dmasync_op_t op);
+static void ichip_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map,
+    bus_dmasync_op_t op);
+static void schizo_intr_enable(void *);
+static void schizo_intr_disable(void *);
+static void schizo_intr_assign(void *);
+static void schizo_intr_clear(void *);
+static int schizo_intr_register(struct schizo_softc *sc, u_int ino);
+static int schizo_get_intrmap(struct schizo_softc *, u_int,
+    bus_addr_t *, bus_addr_t *);
+static timecounter_get_t schizo_get_timecount;
+
+/* Interrupt handlers */
+static driver_filter_t schizo_pci_bus;
+static driver_filter_t schizo_ue;
+static driver_filter_t schizo_ce;
+static driver_filter_t schizo_host_bus;
+static driver_filter_t schizo_cdma;
+
+/* IOMMU support */
+static void schizo_iommu_init(struct schizo_softc *, int, uint32_t);
+
+/*
+ * Methods
+ */
+static device_probe_t schizo_probe;
+static device_attach_t schizo_attach;
+static bus_setup_intr_t schizo_setup_intr;
+static bus_alloc_resource_t schizo_alloc_resource;
+static pcib_maxslots_t schizo_maxslots;
+static pcib_read_config_t schizo_read_config;
+static pcib_write_config_t schizo_write_config;
+static pcib_route_interrupt_t schizo_route_interrupt;
+static ofw_pci_setup_device_t schizo_setup_device;
+
+static device_method_t schizo_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		schizo_probe),
+	DEVMETHOD(device_attach,	schizo_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	ofw_pci_read_ivar),
+	DEVMETHOD(bus_setup_intr,	schizo_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_alloc_resource,	schizo_alloc_resource),
+	DEVMETHOD(bus_activate_resource, ofw_pci_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	ofw_pci_adjust_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+	DEVMETHOD(bus_get_dma_tag,	ofw_pci_get_dma_tag),
+
+	/* pcib interface */
+	DEVMETHOD(pcib_maxslots,	schizo_maxslots),
+	DEVMETHOD(pcib_read_config,	schizo_read_config),
+	DEVMETHOD(pcib_write_config,	schizo_write_config),
+	DEVMETHOD(pcib_route_interrupt,	schizo_route_interrupt),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_node,	ofw_pci_get_node),
+
+	/* ofw_pci interface */
+	DEVMETHOD(ofw_pci_setup_device,	schizo_setup_device),
+
+	DEVMETHOD_END
+};
+
+static devclass_t schizo_devclass;
+
+DEFINE_CLASS_0(pcib, schizo_driver, schizo_methods,
+    sizeof(struct schizo_softc));
+EARLY_DRIVER_MODULE(schizo, nexus, schizo_driver, schizo_devclass, 0, 0,
+    BUS_PASS_BUS);
+
+static SLIST_HEAD(, schizo_softc) schizo_softcs =
+    SLIST_HEAD_INITIALIZER(schizo_softcs);
+
+static const struct intr_controller schizo_ic = {
+	schizo_intr_enable,
+	schizo_intr_disable,
+	schizo_intr_assign,
+	schizo_intr_clear
+};
+
+struct schizo_icarg {
+	struct schizo_softc	*sica_sc;
+	bus_addr_t		sica_map;
+	bus_addr_t		sica_clr;
+};
+
+#define	SCHIZO_CDMA_TIMEOUT	1	/* 1 second per try */
+#define	SCHIZO_CDMA_TRIES	15
+#define	SCHIZO_PERF_CNT_QLTY	100
+
+#define	SCHIZO_SPC_BARRIER(spc, sc, offs, len, flags)			\
+	bus_barrier((sc)->sc_mem_res[(spc)], (offs), (len), (flags))
+#define	SCHIZO_SPC_READ_8(spc, sc, offs)				\
+	bus_read_8((sc)->sc_mem_res[(spc)], (offs))
+#define	SCHIZO_SPC_WRITE_8(spc, sc, offs, v)				\
+	bus_write_8((sc)->sc_mem_res[(spc)], (offs), (v))
+
+#ifndef SCHIZO_DEBUG
+#define	SCHIZO_SPC_SET(spc, sc, offs, reg, v)				\
+	SCHIZO_SPC_WRITE_8((spc), (sc), (offs), (v))
+#else
+#define	SCHIZO_SPC_SET(spc, sc, offs, reg, v) do {			\
+	device_printf((sc)->sc_dev, reg " 0x%016llx -> 0x%016llx\n",	\
+	    (unsigned long long)SCHIZO_SPC_READ_8((spc), (sc), (offs)),	\
+	    (unsigned long long)(v));					\
+	SCHIZO_SPC_WRITE_8((spc), (sc), (offs), (v));			\
+	} while (0)
+#endif
+
+#define	SCHIZO_PCI_READ_8(sc, offs)					\
+	SCHIZO_SPC_READ_8(STX_PCI, (sc), (offs))
+#define	SCHIZO_PCI_WRITE_8(sc, offs, v)					\
+	SCHIZO_SPC_WRITE_8(STX_PCI, (sc), (offs), (v))
+#define	SCHIZO_CTRL_READ_8(sc, offs)					\
+	SCHIZO_SPC_READ_8(STX_CTRL, (sc), (offs))
+#define	SCHIZO_CTRL_WRITE_8(sc, offs, v)				\
+	SCHIZO_SPC_WRITE_8(STX_CTRL, (sc), (offs), (v))
+#define	SCHIZO_PCICFG_READ_8(sc, offs)					\
+	SCHIZO_SPC_READ_8(STX_PCICFG, (sc), (offs))
+#define	SCHIZO_PCICFG_WRITE_8(sc, offs, v)				\
+	SCHIZO_SPC_WRITE_8(STX_PCICFG, (sc), (offs), (v))
+#define	SCHIZO_ICON_READ_8(sc, offs)					\
+	SCHIZO_SPC_READ_8(STX_ICON, (sc), (offs))
+#define	SCHIZO_ICON_WRITE_8(sc, offs, v)				\
+	SCHIZO_SPC_WRITE_8(STX_ICON, (sc), (offs), (v))
+
+#define	SCHIZO_PCI_SET(sc, offs, v)					\
+	SCHIZO_SPC_SET(STX_PCI, (sc), (offs), # offs, (v))
+#define	SCHIZO_CTRL_SET(sc, offs, v)					\
+	SCHIZO_SPC_SET(STX_CTRL, (sc), (offs), # offs, (v))
+
+struct schizo_desc {
+	const char	*sd_string;
+	int		sd_mode;
+	const char	*sd_name;
+};
+
+static const struct schizo_desc schizo_compats[] = {
+	{ "pci108e,8001",	SCHIZO_MODE_SCZ,	"Schizo" },
+#if 0
+	{ "pci108e,8002",	SCHIZO_MODE_XMS,	"XMITS" },
+#endif
+	{ "pci108e,a801",	SCHIZO_MODE_TOM,	"Tomatillo" },
+	{ NULL,			0,			NULL }
+};
+
+static const struct schizo_desc *
+schizo_get_desc(device_t dev)
+{
+	const struct schizo_desc *desc;
+	const char *compat;
+
+	compat = ofw_bus_get_compat(dev);
+	if (compat == NULL)
+		return (NULL);
+	for (desc = schizo_compats; desc->sd_string != NULL; desc++)
+		if (strcmp(desc->sd_string, compat) == 0)
+			return (desc);
+	return (NULL);
+}
+
+static int
+schizo_probe(device_t dev)
+{
+	const char *dtype;
+
+	dtype = ofw_bus_get_type(dev);
+	if (dtype != NULL && strcmp(dtype, OFW_TYPE_PCI) == 0 &&
+	    schizo_get_desc(dev) != NULL) {
+		device_set_desc(dev, "Sun Host-PCI bridge");
+		return (0);
+	}
+	return (ENXIO);
+}
+
+static int
+schizo_attach(device_t dev)
+{
+	const struct schizo_desc *desc;
+	struct schizo_softc *asc, *sc, *osc;
+	struct timecounter *tc;
+	bus_dma_tag_t dmat;
+	uint64_t ino_bitmap, reg;
+	phandle_t node;
+	uint32_t prop, prop_array[2];
+	int i, j, mode, rid, tsbsize;
+
+	sc = device_get_softc(dev);
+	node = ofw_bus_get_node(dev);
+	desc = schizo_get_desc(dev);
+	mode = desc->sd_mode;
+
+	sc->sc_dev = dev;
+	sc->sc_mode = mode;
+	sc->sc_flags = 0;
+
+	/*
+	 * The Schizo has three register banks:
+	 * (0) per-PBM PCI configuration and status registers, but for bus B
+	 *     shared with the UPA64s interrupt mapping register banks
+	 * (1) shared Schizo controller configuration and status registers
+	 * (2) per-PBM PCI configuration space
+	 *
+	 * The Tomatillo has four register banks:
+	 * (0) per-PBM PCI configuration and status registers
+	 * (1) per-PBM Tomatillo controller configuration registers, but on
+	 *     machines having the `jbusppm' device shared with its Estar
+	 *     register bank for bus A
+	 * (2) per-PBM PCI configuration space
+	 * (3) per-PBM interrupt concentrator registers
+	 */
+	sc->sc_half = (bus_get_resource_start(dev, SYS_RES_MEMORY, STX_PCI) >>
+	    20) & 1;
+	for (i = 0; i < (mode == SCHIZO_MODE_SCZ ? SCZ_NREG : TOM_NREG);
+	    i++) {
+		rid = i;
+		sc->sc_mem_res[i] = bus_alloc_resource_any(dev,
+		    SYS_RES_MEMORY, &rid,
+		    (((mode == SCHIZO_MODE_SCZ && ((sc->sc_half == 1 &&
+		    i == STX_PCI) || i == STX_CTRL)) ||
+		    (mode == SCHIZO_MODE_TOM && sc->sc_half == 0 &&
+		    i == STX_CTRL)) ? RF_SHAREABLE : 0) | RF_ACTIVE);
+		if (sc->sc_mem_res[i] == NULL)
+			panic("%s: could not allocate register bank %d",
+			    __func__, i);
+	}
+
+	/*
+	 * Match other Schizos that are already configured against
+	 * the controller base physical address.  This will be the
+	 * same for a pair of devices that share register space.
+	 */
+	osc = NULL;
+	SLIST_FOREACH(asc, &schizo_softcs, sc_link) {
+		if (rman_get_start(asc->sc_mem_res[STX_CTRL]) ==
+		    rman_get_start(sc->sc_mem_res[STX_CTRL])) {
+			/* Found partner. */
+			osc = asc;
+			break;
+		}
+	}
+	if (osc == NULL) {
+		sc->sc_mtx = malloc(sizeof(*sc->sc_mtx), M_DEVBUF,
+		    M_NOWAIT | M_ZERO);
+		if (sc->sc_mtx == NULL)
+			panic("%s: could not malloc mutex", __func__);
+		mtx_init(sc->sc_mtx, "pcib_mtx", NULL, MTX_SPIN);
+	} else {
+		if (sc->sc_mode != SCHIZO_MODE_SCZ)
+			panic("%s: no partner expected", __func__);
+		if (mtx_initialized(osc->sc_mtx) == 0)
+			panic("%s: mutex not initialized", __func__);
+		sc->sc_mtx = osc->sc_mtx;
+	}
+	SLIST_INSERT_HEAD(&schizo_softcs, sc, sc_link);
+
+	if (OF_getprop(node, "portid", &sc->sc_ign, sizeof(sc->sc_ign)) == -1)
+		panic("%s: could not determine IGN", __func__);
+	if (OF_getprop(node, "version#", &sc->sc_ver, sizeof(sc->sc_ver)) ==
+	    -1)
+		panic("%s: could not determine version", __func__);
+	if (mode == SCHIZO_MODE_XMS && OF_getprop(node, "module-revision#",
+	    &sc->sc_mrev, sizeof(sc->sc_mrev)) == -1)
+		panic("%s: could not determine module-revision", __func__);
+	if (OF_getprop(node, "clock-frequency", &prop, sizeof(prop)) == -1)
+		prop = 33000000;
+
+	if (mode == SCHIZO_MODE_XMS && (SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL) &
+	    XMS_PCI_CTRL_X_MODE) != 0) {
+		if (sc->sc_mrev < 1)
+			panic("PCI-X mode unsupported");
+		sc->sc_flags |= SCHIZO_FLAGS_XMODE;
+	}
+
+	device_printf(dev, "%s, version %d, ", desc->sd_name, sc->sc_ver);
+	if (mode == SCHIZO_MODE_XMS)
+		printf("module-revision %d, ", sc->sc_mrev);
+	printf("IGN %#x, bus %c, PCI%s mode, %dMHz\n", sc->sc_ign,
+	    'A' + sc->sc_half, (sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0 ?
+	    "-X" : "", prop / 1000 / 1000);
+
+	/* Set up the PCI interrupt retry timer. */
+	SCHIZO_PCI_SET(sc, STX_PCI_INTR_RETRY_TIM, 5);
+
+	/* Set up the PCI control register. */
+	reg = SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL);
+	reg &= ~(TOM_PCI_CTRL_DTO_IEN | STX_PCI_CTRL_ARB_PARK |
+	    STX_PCI_CTRL_ARB_MASK);
+	reg |= STX_PCI_CTRL_MMU_IEN | STX_PCI_CTRL_SBH_IEN |
+	    STX_PCI_CTRL_ERR_IEN;
+	if (OF_getproplen(node, "no-bus-parking") < 0)
+		reg |= STX_PCI_CTRL_ARB_PARK;
+	if (mode == SCHIZO_MODE_XMS && sc->sc_mrev == 1)
+		reg |= XMS_PCI_CTRL_XMITS10_ARB_MASK;
+	else
+		reg |= STX_PCI_CTRL_ARB_MASK;
+	if (mode == SCHIZO_MODE_TOM) {
+		reg |= TOM_PCI_CTRL_PRM | TOM_PCI_CTRL_PRO | TOM_PCI_CTRL_PRL;
+		if (sc->sc_ver <= 1)	/* revision <= 2.0 */
+			reg |= TOM_PCI_CTRL_DTO_IEN;
+		else
+			reg |= STX_PCI_CTRL_PTO;
+	} else if (mode == SCHIZO_MODE_XMS) {
+		SCHIZO_PCI_SET(sc, XMS_PCI_PARITY_DETECT, 0x3fff);
+		SCHIZO_PCI_SET(sc, XMS_PCI_UPPER_RETRY_COUNTER, 0x3e8);
+		reg |= XMS_PCI_CTRL_X_ERRINT_EN;
+	}
+	SCHIZO_PCI_SET(sc, STX_PCI_CTRL, reg);
+
+	/* Set up the PCI diagnostic register. */
+	reg = SCHIZO_PCI_READ_8(sc, STX_PCI_DIAG);
+	reg &= ~(SCZ_PCI_DIAG_RTRYARB_DIS | STX_PCI_DIAG_RETRY_DIS |
+	    STX_PCI_DIAG_INTRSYNC_DIS);
+	SCHIZO_PCI_SET(sc, STX_PCI_DIAG, reg);
+
+	/*
+	 * Enable DMA write parity error interrupts of version >= 7 (i.e.
+	 * revision >= 2.5) Schizo and XMITS (enabling it on XMITS < 3.0 has
+	 * no effect though).
+	 */
+	if ((mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 7) ||
+	    mode == SCHIZO_MODE_XMS) {
+		reg = SCHIZO_PCI_READ_8(sc, SX_PCI_CFG_ICD);
+		reg |= SX_PCI_CFG_ICD_DMAW_PERR_IEN;
+		SCHIZO_PCI_SET(sc, SX_PCI_CFG_ICD, reg);
+	}
+
+	/*
+	 * On Tomatillo clear the I/O prefetch lengths (workaround for a
+	 * Jalapeno bug).
+	 */
+	if (mode == SCHIZO_MODE_TOM)
+		SCHIZO_PCI_SET(sc, TOM_PCI_IOC_CSR, TOM_PCI_IOC_PW |
+		    (1 << TOM_PCI_IOC_PREF_OFF_SHIFT) | TOM_PCI_IOC_CPRM |
+		    TOM_PCI_IOC_CPRO | TOM_PCI_IOC_CPRL);
+
+	/*
+	 * Hunt through all the interrupt mapping regs and register
+	 * the interrupt controller for our interrupt vectors.  We do
+	 * this early in order to be able to catch stray interrupts.
+	 * This is complicated by the fact that a pair of Schizo PBMs
+	 * shares one IGN.
+	 */
+	i = OF_getprop(node, "ino-bitmap", (void *)prop_array,
+	    sizeof(prop_array));
+	if (i != -1)
+		ino_bitmap = ((uint64_t)prop_array[1] << 32) | prop_array[0];
+	else {
+		/*
+		 * If the ino-bitmap property is missing, just provide the
+		 * default set of interrupts for this controller and let
+		 * schizo_setup_intr() take care of child interrupts.
+		 */
+		if (sc->sc_half == 0)
+			ino_bitmap = (1ULL << STX_UE_INO) |
+			    (1ULL << STX_CE_INO) |
+			    (1ULL << STX_PCIERR_A_INO) |
+			    (1ULL << STX_BUS_INO);
+		else
+			ino_bitmap = 1ULL << STX_PCIERR_B_INO;
+	}
+	for (i = 0; i <= STX_MAX_INO; i++) {
+		if ((ino_bitmap & (1ULL << i)) == 0)
+			continue;
+		if (i == STX_FB0_INO || i == STX_FB1_INO)
+			/* Leave for upa(4). */
+			continue;
+		j = schizo_intr_register(sc, i);
+		if (j != 0)
+			device_printf(dev, "could not register interrupt "
+			    "controller for INO %d (%d)\n", i, j);
+	}
+
+	/*
+	 * Setup Safari/JBus performance counter 0 in bus cycle counting
+	 * mode as timecounter.  Unfortunately, this is broken with at
+	 * least the version 4 Tomatillos found in Fire V120 and Blade
+	 * 1500, which apparently actually count some different event at
+	 * ~0.5 and 3MHz respectively instead (also when running in full
+	 * power mode).  Besides, one counter seems to be shared by a
+	 * "pair" of Tomatillos, too.
+	 */
+	if (sc->sc_half == 0) {
+		SCHIZO_CTRL_SET(sc, STX_CTRL_PERF,
+		    (STX_CTRL_PERF_DIS << STX_CTRL_PERF_CNT1_SHIFT) |
+		    (STX_CTRL_PERF_BUSCYC << STX_CTRL_PERF_CNT0_SHIFT));
+		tc = malloc(sizeof(*tc), M_DEVBUF, M_NOWAIT | M_ZERO);
+		if (tc == NULL)
+			panic("%s: could not malloc timecounter", __func__);
+		tc->tc_get_timecount = schizo_get_timecount;
+		tc->tc_counter_mask = STX_CTRL_PERF_CNT_MASK;
+		if (OF_getprop(OF_peer(0), "clock-frequency", &prop,
+		    sizeof(prop)) == -1)
+			panic("%s: could not determine clock frequency",
+			    __func__);
+		tc->tc_frequency = prop;
+		tc->tc_name = strdup(device_get_nameunit(dev), M_DEVBUF);
+		if (mode == SCHIZO_MODE_SCZ)
+			tc->tc_quality = SCHIZO_PERF_CNT_QLTY;
+		else
+			tc->tc_quality = -SCHIZO_PERF_CNT_QLTY;
+		tc->tc_priv = sc;
+		tc_init(tc);
+	}
+
+	/*
+	 * Set up the IOMMU.  Schizo, Tomatillo and XMITS all have
+	 * one per PBM.  Schizo and XMITS additionally have a streaming
+	 * buffer, in Schizo version < 5 (i.e. revision < 2.3) it's
+	 * affected by several errata though.  However, except for context
+	 * flushes, taking advantage of it should be okay even with those.
+	 */
+	memcpy(&sc->sc_dma_methods, &iommu_dma_methods,
+	    sizeof(sc->sc_dma_methods));
+	sc->sc_is.sis_sc = sc;
+	sc->sc_is.sis_is.is_flags = IOMMU_PRESERVE_PROM;
+	sc->sc_is.sis_is.is_pmaxaddr = IOMMU_MAXADDR(STX_IOMMU_BITS);
+	sc->sc_is.sis_is.is_sb[0] = sc->sc_is.sis_is.is_sb[1] = 0;
+	if (OF_getproplen(node, "no-streaming-cache") < 0)
+		sc->sc_is.sis_is.is_sb[0] = STX_PCI_STRBUF;
+
+#define	TSBCASE(x)							\
+	case (IOTSB_BASESZ << (x)) << (IO_PAGE_SHIFT - IOTTE_SHIFT):	\
+		tsbsize = (x);						\
+		break;							\
+
+	i = OF_getprop(node, "virtual-dma", (void *)prop_array,
+	    sizeof(prop_array));
+	if (i == -1 || i != sizeof(prop_array))
+		schizo_iommu_init(sc, 7, -1);
+	else {
+		switch (prop_array[1]) {
+		TSBCASE(1);
+		TSBCASE(2);
+		TSBCASE(3);
+		TSBCASE(4);
+		TSBCASE(5);
+		TSBCASE(6);
+		TSBCASE(7);
+		TSBCASE(8);
+		default:
+			panic("%s: unsupported DVMA size 0x%x",
+			    __func__, prop_array[1]);
+			/* NOTREACHED */
+		}
+		schizo_iommu_init(sc, tsbsize, prop_array[0]);
+	}
+
+#undef TSBCASE
+
+	/* Create our DMA tag. */
+	if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
+	    sc->sc_is.sis_is.is_pmaxaddr, ~0, NULL, NULL,
+	    sc->sc_is.sis_is.is_pmaxaddr, 0xff, 0xffffffff, 0, NULL, NULL,
+	    &dmat) != 0)
+		panic("%s: could not create PCI DMA tag", __func__);
+	dmat->dt_cookie = &sc->sc_is;
+	dmat->dt_mt = &sc->sc_dma_methods;
+
+	if (ofw_pci_attach_common(dev, dmat, STX_IO_SIZE, STX_MEM_SIZE) != 0)
+		panic("%s: ofw_pci_attach_common() failed", __func__);
+
+	/* Clear any pending PCI error bits. */
+	PCIB_WRITE_CONFIG(dev, sc->sc_ops.sc_pci_secbus, STX_CS_DEVICE,
+	    STX_CS_FUNC, PCIR_STATUS, PCIB_READ_CONFIG(dev,
+	    sc->sc_ops.sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS,
+	    2), 2);
+	SCHIZO_PCI_SET(sc, STX_PCI_CTRL, SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL));
+	SCHIZO_PCI_SET(sc, STX_PCI_AFSR, SCHIZO_PCI_READ_8(sc, STX_PCI_AFSR));
+
+	/*
+	 * Establish handlers for interesting interrupts...
+	 * Someone at Sun clearly was smoking crack; with Schizos PCI
+	 * bus error interrupts for one PBM can be routed to the other
+	 * PBM though we obviously need to use the softc of the former
+	 * as the argument for the interrupt handler and the softc of
+	 * the latter as the argument for the interrupt controller.
+	 */
+	if (sc->sc_half == 0) {
+		if ((ino_bitmap & (1ULL << STX_PCIERR_A_INO)) != 0 ||
+		    (osc != NULL && ((struct schizo_icarg *)intr_vectors[
+		    INTMAP_VEC(sc->sc_ign, STX_PCIERR_A_INO)].iv_icarg)->
+		    sica_sc == osc))
+			/*
+			 * We are the driver for PBM A and either also
+			 * registered the interrupt controller for us or
+			 * the driver for PBM B has probed first and
+			 * registered it for us.
+			 */
+			schizo_set_intr(sc, 0, STX_PCIERR_A_INO,
+			    schizo_pci_bus);
+		if ((ino_bitmap & (1ULL << STX_PCIERR_B_INO)) != 0 &&
+		    osc != NULL)
+			/*
+			 * We are the driver for PBM A but registered
+			 * the interrupt controller for PBM B, i.e. the
+			 * driver for PBM B attached first but couldn't
+			 * set up a handler for PBM B.
+			 */
+			schizo_set_intr(osc, 0, STX_PCIERR_B_INO,
+			    schizo_pci_bus);
+	} else {
+		if ((ino_bitmap & (1ULL << STX_PCIERR_B_INO)) != 0 ||
+		    (osc != NULL && ((struct schizo_icarg *)intr_vectors[
+		    INTMAP_VEC(sc->sc_ign, STX_PCIERR_B_INO)].iv_icarg)->
+		    sica_sc == osc))
+			/*
+			 * We are the driver for PBM B and either also
+			 * registered the interrupt controller for us or
+			 * the driver for PBM A has probed first and
+			 * registered it for us.
+			 */
+			schizo_set_intr(sc, 0, STX_PCIERR_B_INO,
+			    schizo_pci_bus);
+		if ((ino_bitmap & (1ULL << STX_PCIERR_A_INO)) != 0 &&
+		    osc != NULL)
+			/*
+			 * We are the driver for PBM B but registered
+			 * the interrupt controller for PBM A, i.e. the
+			 * driver for PBM A attached first but couldn't
+			 * set up a handler for PBM A.
+			 */
+			schizo_set_intr(osc, 0, STX_PCIERR_A_INO,
+			    schizo_pci_bus);
+	}
+	if ((ino_bitmap & (1ULL << STX_UE_INO)) != 0)
+		schizo_set_intr(sc, 1, STX_UE_INO, schizo_ue);
+	if ((ino_bitmap & (1ULL << STX_CE_INO)) != 0)
+		schizo_set_intr(sc, 2, STX_CE_INO, schizo_ce);
+	if ((ino_bitmap & (1ULL << STX_BUS_INO)) != 0)
+		schizo_set_intr(sc, 3, STX_BUS_INO, schizo_host_bus);
+
+	/*
+	 * According to the Schizo Errata I-13, consistent DMA flushing/
+	 * syncing is FUBAR in version < 5 (i.e. revision < 2.3) bridges,
+	 * so we can't use it and need to live with the consequences.  With
+	 * Schizo version >= 5, CDMA flushing/syncing is usable but requires
+	 * the workaround described in Schizo Errata I-23.  With Tomatillo
+	 * and XMITS, CDMA flushing/syncing works as expected, Tomatillo
+	 * version <= 4 (i.e. revision <= 2.3) bridges additionally require
+	 * a block store after a write to TOMXMS_PCI_DMA_SYNC_PEND though.
+	 */
+	if ((sc->sc_mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 5) ||
+	    sc->sc_mode == SCHIZO_MODE_TOM ||
+	    sc->sc_mode == SCHIZO_MODE_XMS) {
+		if (sc->sc_mode == SCHIZO_MODE_SCZ) {
+			sc->sc_dma_methods.dm_dmamap_sync =
+			    schizo_dmamap_sync;
+			sc->sc_cdma_state = SCHIZO_CDMA_STATE_IDLE;
+			/*
+			 * Some firmware versions include the CDMA interrupt
+			 * at RID 4 but most don't.  With the latter we add
+			 * it ourselves at the spare RID 5.
+			 */
+			i = INTINO(bus_get_resource_start(dev, SYS_RES_IRQ,
+			    4));
+			if (i == STX_CDMA_A_INO || i == STX_CDMA_B_INO) {
+				sc->sc_cdma_vec = INTMAP_VEC(sc->sc_ign, i);
+				(void)schizo_get_intrmap(sc, i,
+				   &sc->sc_cdma_map, &sc->sc_cdma_clr);
+				schizo_set_intr(sc, 4, i, schizo_cdma);
+			} else {
+				i = STX_CDMA_A_INO + sc->sc_half;
+				sc->sc_cdma_vec = INTMAP_VEC(sc->sc_ign, i);
+				if (bus_set_resource(dev, SYS_RES_IRQ, 5,
+				    sc->sc_cdma_vec, 1) != 0)
+					panic("%s: failed to add CDMA "
+					    "interrupt", __func__);
+				j = schizo_intr_register(sc, i);
+				if (j != 0)
+					panic("%s: could not register "
+					    "interrupt controller for CDMA "
+					    "(%d)", __func__, j);
+				(void)schizo_get_intrmap(sc, i,
+				   &sc->sc_cdma_map, &sc->sc_cdma_clr);
+				schizo_set_intr(sc, 5, i, schizo_cdma);
+			}
+		} else {
+			if (sc->sc_mode == SCHIZO_MODE_XMS)
+				mtx_init(&sc->sc_sync_mtx, "pcib_sync_mtx",
+				    NULL, MTX_SPIN);
+			sc->sc_sync_val = 1ULL << (STX_PCIERR_A_INO +
+			    sc->sc_half);
+			sc->sc_dma_methods.dm_dmamap_sync =
+			    ichip_dmamap_sync;
+		}
+		if (sc->sc_mode == SCHIZO_MODE_TOM && sc->sc_ver <= 4)
+			sc->sc_flags |= SCHIZO_FLAGS_BSWAR;
+	}
+
+	/*
+	 * Set the latency timer register as this isn't always done by the
+	 * firmware.
+	 */
+	PCIB_WRITE_CONFIG(dev, sc->sc_ops.sc_pci_secbus, STX_CS_DEVICE,
+	    STX_CS_FUNC, PCIR_LATTIMER, OFW_PCI_LATENCY, 1);
+
+#define	SCHIZO_SYSCTL_ADD_UINT(name, arg, desc)				\
+	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),			\
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,	\
+	    (name), CTLFLAG_RD, (arg), 0, (desc))
+
+	SCHIZO_SYSCTL_ADD_UINT("dma_ce", &sc->sc_stats_dma_ce,
+	    "DMA correctable errors");
+	SCHIZO_SYSCTL_ADD_UINT("pci_non_fatal", &sc->sc_stats_pci_non_fatal,
+	    "PCI bus non-fatal errors");
+
+#undef SCHIZO_SYSCTL_ADD_UINT
+
+	device_add_child(dev, "pci", -1);
+	return (bus_generic_attach(dev));
+}
+
+static void
+schizo_set_intr(struct schizo_softc *sc, u_int index, u_int ino,
+    driver_filter_t handler)
+{
+	u_long vec;
+	int rid;
+
+	rid = index;
+	sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev,
+	    SYS_RES_IRQ, &rid, RF_ACTIVE);
+	if (sc->sc_irq_res[index] == NULL ||
+	    INTINO(vec = rman_get_start(sc->sc_irq_res[index])) != ino ||
+	    INTIGN(vec) != sc->sc_ign ||
+	    intr_vectors[vec].iv_ic != &schizo_ic ||
+	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index],
+	    INTR_TYPE_MISC | INTR_BRIDGE, handler, NULL, sc,
+	    &sc->sc_ihand[index]) != 0)
+		panic("%s: failed to set up interrupt %d", __func__, index);
+}
+
+static int
+schizo_intr_register(struct schizo_softc *sc, u_int ino)
+{
+	struct schizo_icarg *sica;
+	bus_addr_t intrclr, intrmap;
+	int error;
+
+	if (schizo_get_intrmap(sc, ino, &intrmap, &intrclr) == 0)
+		return (ENXIO);
+	sica = malloc(sizeof(*sica), M_DEVBUF, M_NOWAIT);
+	if (sica == NULL)
+		return (ENOMEM);
+	sica->sica_sc = sc;
+	sica->sica_map = intrmap;
+	sica->sica_clr = intrclr;
+#ifdef SCHIZO_DEBUG
+	device_printf(sc->sc_dev, "intr map (INO %d) %#lx: %#lx, clr: %#lx\n",
+	    ino, (u_long)intrmap, (u_long)SCHIZO_PCI_READ_8(sc, intrmap),
+	    (u_long)intrclr);
+#endif
+	error = (intr_controller_register(INTMAP_VEC(sc->sc_ign, ino),
+	    &schizo_ic, sica));
+	if (error != 0)
+		free(sica, M_DEVBUF);
+	return (error);
+}
+
+static int
+schizo_get_intrmap(struct schizo_softc *sc, u_int ino,
+    bus_addr_t *intrmapptr, bus_addr_t *intrclrptr)
+{
+	bus_addr_t intrclr, intrmap;
+	uint64_t mr;
+
+	/*
+	 * XXX we only look for INOs rather than INRs since the firmware
+	 * may not provide the IGN and the IGN is constant for all devices
+	 * on that PCI controller.
+	 */
+
+	if (ino > STX_MAX_INO) {
+		device_printf(sc->sc_dev, "out of range INO %d requested\n",
+		    ino);
+		return (0);
+	}
+
+	intrmap = STX_PCI_IMAP_BASE + (ino << 3);
+	intrclr = STX_PCI_ICLR_BASE + (ino << 3);
+	mr = SCHIZO_PCI_READ_8(sc, intrmap);
+	if (INTINO(mr) != ino) {
+		device_printf(sc->sc_dev,
+		    "interrupt map entry does not match INO (%d != %d)\n",
+		    (int)INTINO(mr), ino);
+		return (0);
+	}
+
+	if (intrmapptr != NULL)
+		*intrmapptr = intrmap;
+	if (intrclrptr != NULL)
+		*intrclrptr = intrclr;
+	return (1);
+}
+
+/*
+ * Interrupt handlers
+ */
+static int
+schizo_pci_bus(void *arg)
+{
+	struct schizo_softc *sc = arg;
+	uint64_t afar, afsr, csr, iommu, xstat;
+	uint32_t status;
+	u_int fatal;
+
+	fatal = 0;
+
+	mtx_lock_spin(sc->sc_mtx);
+
+	afar = SCHIZO_PCI_READ_8(sc, STX_PCI_AFAR);
+	afsr = SCHIZO_PCI_READ_8(sc, STX_PCI_AFSR);
+	csr = SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL);
+	iommu = SCHIZO_PCI_READ_8(sc, STX_PCI_IOMMU);
+	if ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0)
+		xstat = SCHIZO_PCI_READ_8(sc, XMS_PCI_X_ERR_STAT);
+	else
+		xstat = 0;
+	status = PCIB_READ_CONFIG(sc->sc_dev, sc->sc_ops.sc_pci_secbus,
+	    STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS, 2);
+
+	/*
+	 * IOMMU errors are only fatal on Tomatillo and there also only if
+	 * target abort was not signaled.
+	 */
+	if ((csr & STX_PCI_CTRL_MMU_ERR) != 0 &&
+	    (iommu & TOM_PCI_IOMMU_ERR) != 0 &&
+	    ((status & PCIM_STATUS_STABORT) == 0 ||
+	    ((iommu & TOM_PCI_IOMMU_ERRMASK) != TOM_PCI_IOMMU_INVALID_ERR &&
+	    (iommu & TOM_PCI_IOMMU_ERR_ILLTSBTBW) == 0 &&
+	    (iommu & TOM_PCI_IOMMU_ERR_BAD_VA) == 0)))
+		fatal = 1;
+	else if ((status & PCIM_STATUS_STABORT) != 0)
+		fatal = 1;
+	if ((status & (PCIM_STATUS_PERR | PCIM_STATUS_SERR |
+	    PCIM_STATUS_RMABORT | PCIM_STATUS_RTABORT |
+	    PCIM_STATUS_MDPERR)) != 0 ||
+	    (csr & (SCZ_PCI_CTRL_BUS_UNUS | TOM_PCI_CTRL_DTO_ERR |
+	    STX_PCI_CTRL_TTO_ERR | STX_PCI_CTRL_RTRY_ERR |
+	    SCZ_PCI_CTRL_SBH_ERR | STX_PCI_CTRL_SERR)) != 0 ||
+	    (afsr & (STX_PCI_AFSR_P_MA | STX_PCI_AFSR_P_TA |
+	    STX_PCI_AFSR_P_RTRY | STX_PCI_AFSR_P_PERR | STX_PCI_AFSR_P_TTO |
+	    STX_PCI_AFSR_P_UNUS)) != 0)
+		fatal = 1;
+	if (xstat & (XMS_PCI_X_ERR_STAT_P_SC_DSCRD |
+	    XMS_PCI_X_ERR_STAT_P_SC_TTO | XMS_PCI_X_ERR_STAT_P_SDSTAT |
+	    XMS_PCI_X_ERR_STAT_P_SMMU | XMS_PCI_X_ERR_STAT_P_CDSTAT |
+	    XMS_PCI_X_ERR_STAT_P_CMMU | XMS_PCI_X_ERR_STAT_PERR_RCV))
+		fatal = 1;
+	if (fatal == 0)
+		sc->sc_stats_pci_non_fatal++;
+
+	device_printf(sc->sc_dev, "PCI bus %c error AFAR %#llx AFSR %#llx "
+	    "PCI CSR %#llx IOMMU %#llx PCI-X %#llx STATUS %#x\n",
+	    'A' + sc->sc_half, (unsigned long long)afar,
+	    (unsigned long long)afsr, (unsigned long long)csr,
+	    (unsigned long long)iommu, (unsigned long long)xstat, status);
+
+	/* Clear the error bits that we caught. */
+	PCIB_WRITE_CONFIG(sc->sc_dev, sc->sc_ops.sc_pci_secbus, STX_CS_DEVICE,
+	    STX_CS_FUNC, PCIR_STATUS, status, 2);
+	SCHIZO_PCI_WRITE_8(sc, STX_PCI_CTRL, csr);
+	SCHIZO_PCI_WRITE_8(sc, STX_PCI_AFSR, afsr);
+	SCHIZO_PCI_WRITE_8(sc, STX_PCI_IOMMU, iommu);
+	if ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0)
+		SCHIZO_PCI_WRITE_8(sc, XMS_PCI_X_ERR_STAT, xstat);
+
+	mtx_unlock_spin(sc->sc_mtx);
+
+	if (fatal != 0)
+		panic("%s: fatal PCI bus error",
+		    device_get_nameunit(sc->sc_dev));
+	return (FILTER_HANDLED);
+}
+
+static int
+schizo_ue(void *arg)
+{
+	struct schizo_softc *sc = arg;
+	uint64_t afar, afsr;
+	int i;
+
+	afar = SCHIZO_CTRL_READ_8(sc, STX_CTRL_UE_AFAR);
+	for (i = 0; i < 1000; i++)
+		if (((afsr = SCHIZO_CTRL_READ_8(sc, STX_CTRL_UE_AFSR)) &
+		    STX_CTRL_CE_AFSR_ERRPNDG) == 0)
+			break;
+	panic("%s: uncorrectable DMA error AFAR %#llx AFSR %#llx",
+	    device_get_nameunit(sc->sc_dev), (unsigned long long)afar,
+	    (unsigned long long)afsr);
+	return (FILTER_HANDLED);
+}
+
+static int
+schizo_ce(void *arg)
+{
+	struct schizo_softc *sc = arg;
+	uint64_t afar, afsr;
+	int i;
+
+	mtx_lock_spin(sc->sc_mtx);
+
+	afar = SCHIZO_CTRL_READ_8(sc, STX_CTRL_CE_AFAR);
+	for (i = 0; i < 1000; i++)
+		if (((afsr = SCHIZO_CTRL_READ_8(sc, STX_CTRL_UE_AFSR)) &
+		    STX_CTRL_CE_AFSR_ERRPNDG) == 0)
+			break;
+	sc->sc_stats_dma_ce++;
+	device_printf(sc->sc_dev,
+	    "correctable DMA error AFAR %#llx AFSR %#llx\n",
+	    (unsigned long long)afar, (unsigned long long)afsr);
+
+	/* Clear the error bits that we caught. */
+	SCHIZO_CTRL_WRITE_8(sc, STX_CTRL_UE_AFSR, afsr);
+
+	mtx_unlock_spin(sc->sc_mtx);
+
+	return (FILTER_HANDLED);
+}
+
+static int
+schizo_host_bus(void *arg)
+{
+	struct schizo_softc *sc = arg;
+	uint64_t errlog;
+
+	errlog = SCHIZO_CTRL_READ_8(sc, STX_CTRL_BUS_ERRLOG);
+	panic("%s: %s error %#llx", device_get_nameunit(sc->sc_dev),
+	    sc->sc_mode == SCHIZO_MODE_TOM ? "JBus" : "Safari",
+	    (unsigned long long)errlog);
+	return (FILTER_HANDLED);
+}
+
+static int
+schizo_cdma(void *arg)
+{
+	struct schizo_softc *sc = arg;
+
+	atomic_cmpset_32(&sc->sc_cdma_state, SCHIZO_CDMA_STATE_PENDING,
+	    SCHIZO_CDMA_STATE_RECEIVED);
+	return (FILTER_HANDLED);
+}
+
+static void
+schizo_iommu_init(struct schizo_softc *sc, int tsbsize, uint32_t dvmabase)
+{
+
+	/* Punch in our copies. */
+	sc->sc_is.sis_is.is_bustag = rman_get_bustag(sc->sc_mem_res[STX_PCI]);
+	sc->sc_is.sis_is.is_bushandle =
+	    rman_get_bushandle(sc->sc_mem_res[STX_PCI]);
+	sc->sc_is.sis_is.is_iommu = STX_PCI_IOMMU;
+	sc->sc_is.sis_is.is_dtag = STX_PCI_IOMMU_TLB_TAG_DIAG;
+	sc->sc_is.sis_is.is_ddram = STX_PCI_IOMMU_TLB_DATA_DIAG;
+	sc->sc_is.sis_is.is_dqueue = STX_PCI_IOMMU_QUEUE_DIAG;
+	sc->sc_is.sis_is.is_dva = STX_PCI_IOMMU_SVADIAG;
+	sc->sc_is.sis_is.is_dtcmp = STX_PCI_IOMMU_TLB_CMP_DIAG;
+
+	iommu_init(device_get_nameunit(sc->sc_dev),
+	    (struct iommu_state *)&sc->sc_is, tsbsize, dvmabase, 0);
+}
+
+static int
+schizo_maxslots(device_t dev)
+{
+	struct schizo_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (sc->sc_mode == SCHIZO_MODE_SCZ)
+		return (sc->sc_half == 0 ? 4 : 6);
+
+	/* XXX: is this correct? */
+	return (PCI_SLOTMAX);
+}
+
+static uint32_t
+schizo_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
+    int width)
+{
+	struct schizo_softc *sc;
+
+	sc = device_get_softc(dev);
+	/*
+	 * The Schizo bridges contain a dupe of their header at 0x80.
+	 */
+	if (sc->sc_mode == SCHIZO_MODE_SCZ &&
+	    bus == sc->sc_ops.sc_pci_secbus && slot == STX_CS_DEVICE &&
+	    func == STX_CS_FUNC && reg + width > 0x80)
+		return (0);
+
+	return (ofw_pci_read_config_common(dev, PCI_REGMAX, STX_CONF_OFF(bus,
+	    slot, func, reg), bus, slot, func, reg, width));
+}
+
+static void
+schizo_write_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, uint32_t val, int width)
+{
+
+	ofw_pci_write_config_common(dev, PCI_REGMAX, STX_CONF_OFF(bus, slot,
+	    func, reg), bus, slot, func, reg, val, width);
+}
+
+static int
+schizo_route_interrupt(device_t bridge, device_t dev, int pin)
+{
+	ofw_pci_intr_t mintr;
+
+	mintr = ofw_pci_route_interrupt_common(bridge, dev, pin);
+	if (!PCI_INTERRUPT_VALID(mintr))
+		device_printf(bridge,
+		    "could not route pin %d for device %d.%d\n",
+		    pin, pci_get_slot(dev), pci_get_function(dev));
+	return (mintr);
+}
+
+static void
+schizo_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
+{
+	struct timeval cur, end;
+	struct schizo_iommu_state *sis = dt->dt_cookie;
+	struct schizo_softc *sc = sis->sis_sc;
+	int i, res;
+#ifdef INVARIANTS
+	register_t pil;
+#endif
+
+	if ((map->dm_flags & DMF_STREAMED) != 0) {
+		iommu_dma_methods.dm_dmamap_sync(dt, map, op);
+		return;
+	}
+
+	if ((map->dm_flags & DMF_LOADED) == 0)
+		return;
+
+	if ((op & BUS_DMASYNC_POSTREAD) != 0) {
+		/*
+		 * Note that in order to allow this function to be called from
+		 * filters we would need to use a spin mutex for serialization
+		 * but given that these disable interrupts we have to emulate
+		 * one.
+		 */
+		critical_enter();
+		KASSERT((rdpr(pstate) & PSTATE_IE) != 0,
+		    ("%s: interrupts disabled", __func__));
+		KASSERT((pil = rdpr(pil)) <= PIL_BRIDGE,
+		    ("%s: PIL too low (%ld)", __func__, pil));
+		for (; atomic_cmpset_acq_32(&sc->sc_cdma_state,
+		    SCHIZO_CDMA_STATE_IDLE, SCHIZO_CDMA_STATE_PENDING) == 0;)
+			;
+		SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_map,
+		    INTMAP_ENABLE(sc->sc_cdma_vec, PCPU_GET(mid)));
+		for (i = 0; i < SCHIZO_CDMA_TRIES; i++) {
+			if (i > 0)
+				printf("%s: try %d\n", __func__, i);
+			SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_clr,
+			    INTCLR_RECEIVED);
+			microuptime(&cur);
+			end.tv_sec = SCHIZO_CDMA_TIMEOUT;
+			end.tv_usec = 0;
+			timevaladd(&end, &cur);
+			for (; (res = atomic_cmpset_rel_32(&sc->sc_cdma_state,
+			    SCHIZO_CDMA_STATE_RECEIVED,
+			    SCHIZO_CDMA_STATE_IDLE)) == 0 &&
+			    timevalcmp(&cur, &end, <=);)
+				microuptime(&cur);
+			if (res != 0)
+				break;
+		}
+		if (res == 0)
+			panic("%s: DMA does not sync", __func__);
+		critical_exit();
+	}
+
+	if ((op & BUS_DMASYNC_PREWRITE) != 0)
+		membar(Sync);
+}
+
+static void
+ichip_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
+{
+	struct timeval cur, end;
+	struct schizo_iommu_state *sis = dt->dt_cookie;
+	struct schizo_softc *sc = sis->sis_sc;
+	uint64_t reg;
+
+	if ((map->dm_flags & DMF_STREAMED) != 0) {
+		iommu_dma_methods.dm_dmamap_sync(dt, map, op);
+		return;
+	}
+
+	if ((map->dm_flags & DMF_LOADED) == 0)
+		return;
+
+	if ((op & BUS_DMASYNC_POSTREAD) != 0) {
+		if (sc->sc_mode == SCHIZO_MODE_XMS)
+			mtx_lock_spin(&sc->sc_sync_mtx);
+		SCHIZO_PCI_WRITE_8(sc, TOMXMS_PCI_DMA_SYNC_PEND,
+		    sc->sc_sync_val);
+		microuptime(&cur);
+		end.tv_sec = 1;
+		end.tv_usec = 0;
+		timevaladd(&end, &cur);
+		for (; ((reg = SCHIZO_PCI_READ_8(sc,
+		    TOMXMS_PCI_DMA_SYNC_PEND)) & sc->sc_sync_val) != 0 &&
+		    timevalcmp(&cur, &end, <=);)
+			microuptime(&cur);
+		if ((reg & sc->sc_sync_val) != 0)
+			panic("%s: DMA does not sync", __func__);
+		if (sc->sc_mode == SCHIZO_MODE_XMS)
+			mtx_unlock_spin(&sc->sc_sync_mtx);
+		else if ((sc->sc_flags & SCHIZO_FLAGS_BSWAR) != 0) {
+			ofw_pci_dmamap_sync_stst_order_common();
+			return;
+		}
+	}
+
+	if ((op & BUS_DMASYNC_PREWRITE) != 0)
+		membar(Sync);
+}
+
+static void
+schizo_intr_enable(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct schizo_icarg *sica = iv->iv_icarg;
+
+	SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_map,
+	    INTMAP_ENABLE(iv->iv_vec, iv->iv_mid));
+}
+
+static void
+schizo_intr_disable(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct schizo_icarg *sica = iv->iv_icarg;
+
+	SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_map, iv->iv_vec);
+}
+
+static void
+schizo_intr_assign(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct schizo_icarg *sica = iv->iv_icarg;
+
+	SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_map, INTMAP_TID(
+	    SCHIZO_PCI_READ_8(sica->sica_sc, sica->sica_map), iv->iv_mid));
+}
+
+static void
+schizo_intr_clear(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct schizo_icarg *sica = iv->iv_icarg;
+
+	SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_clr, INTCLR_IDLE);
+}
+
+static int
+schizo_setup_intr(device_t dev, device_t child, struct resource *ires,
+    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
+    void **cookiep)
+{
+	struct schizo_softc *sc;
+	u_long vec;
+	int error;
+
+	sc = device_get_softc(dev);
+	/*
+	 * Make sure the vector is fully specified.
+	 */
+	vec = rman_get_start(ires);
+	if (INTIGN(vec) != sc->sc_ign) {
+		device_printf(dev, "invalid interrupt vector 0x%lx\n", vec);
+		return (EINVAL);
+	}
+
+	if (intr_vectors[vec].iv_ic == &schizo_ic) {
+		/*
+		 * Ensure we use the right softc in case the interrupt
+		 * is routed to our companion PBM for some odd reason.
+		 */
+		sc = ((struct schizo_icarg *)intr_vectors[vec].iv_icarg)->
+		    sica_sc;
+	} else if (intr_vectors[vec].iv_ic == NULL) {
+		/*
+		 * Work around broken firmware which misses entries in
+		 * the ino-bitmap.
+		 */
+		error = schizo_intr_register(sc, INTINO(vec));
+		if (error != 0) {
+			device_printf(dev, "could not register interrupt "
+			    "controller for vector 0x%lx (%d)\n", vec, error);
+			return (error);
+		}
+		if (bootverbose)
+			device_printf(dev, "belatedly registered as "
+			    "interrupt controller for vector 0x%lx\n", vec);
+	} else {
+		device_printf(dev,
+		    "invalid interrupt controller for vector 0x%lx\n", vec);
+		return (EINVAL);
+	}
+	return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr,
+	    arg, cookiep));
+}
+
+static struct resource *
+schizo_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct schizo_softc *sc;
+
+	if (type == SYS_RES_IRQ) {
+		sc = device_get_softc(bus);
+		start = end = INTMAP_VEC(sc->sc_ign, end);
+	}
+	return (ofw_pci_alloc_resource(bus, child, type, rid, start, end,
+	    count, flags));
+}
+
+static void
+schizo_setup_device(device_t bus, device_t child)
+{
+	struct schizo_softc *sc;
+	uint64_t reg;
+	int capreg;
+
+	sc = device_get_softc(bus);
+	/*
+	 * Disable bus parking in order to work around a bus hang caused by
+	 * Casinni/Skyhawk combinations.
+	 */
+	if (OF_getproplen(ofw_bus_get_node(child), "pci-req-removal") >= 0)
+		SCHIZO_PCI_SET(sc, STX_PCI_CTRL, SCHIZO_PCI_READ_8(sc,
+		    STX_PCI_CTRL) & ~STX_PCI_CTRL_ARB_PARK);
+
+	if (sc->sc_mode == SCHIZO_MODE_XMS) {
+		/* XMITS NCPQ WAR: set outstanding split transactions to 1. */
+		if ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0 &&
+		    (pci_read_config(child, PCIR_HDRTYPE, 1) &
+		    PCIM_HDRTYPE) != PCIM_HDRTYPE_BRIDGE &&
+		    pci_find_cap(child, PCIY_PCIX, &capreg) == 0)
+			pci_write_config(child, capreg + PCIXR_COMMAND,
+			    pci_read_config(child, capreg + PCIXR_COMMAND,
+			    2) & 0x7c, 2);
+		/* XMITS 3.x WAR: set BUGCNTL iff value is unexpected. */
+		if (sc->sc_mrev >= 4) {
+			reg = ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0 ?
+			    0xa0UL : 0xffUL) << XMS_PCI_X_DIAG_BUGCNTL_SHIFT;
+			if ((SCHIZO_PCI_READ_8(sc, XMS_PCI_X_DIAG) &
+			    XMS_PCI_X_DIAG_BUGCNTL_MASK) != reg)
+				SCHIZO_PCI_SET(sc, XMS_PCI_X_DIAG, reg);
+		}
+	}
+}
+
+static u_int
+schizo_get_timecount(struct timecounter *tc)
+{
+	struct schizo_softc *sc;
+
+	sc = tc->tc_priv;
+	return ((SCHIZO_CTRL_READ_8(sc, STX_CTRL_PERF_CNT) &
+	    (STX_CTRL_PERF_CNT_MASK << STX_CTRL_PERF_CNT_CNT0_SHIFT)) >>
+	    STX_CTRL_PERF_CNT_CNT0_SHIFT);
+}


Property changes on: trunk/sys/sparc64/pci/schizo.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/schizoreg.h
===================================================================
--- trunk/sys/sparc64/pci/schizoreg.h	                        (rev 0)
+++ trunk/sys/sparc64/pci/schizoreg.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,358 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 Jason L. Wright (jason at thought.net)
+ * Copyright (c) 2005 by Marius Strobl <marius at 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, 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 PARTICULLAR 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.
+ *
+ *	from: OpenBSD: schizoreg.h,v 1.8 2005/05/19 18:28:59 mickey Exp
+ * $FreeBSD: stable/10/sys/sparc64/pci/schizoreg.h 292789 2015-12-27 19:37:47Z marius $
+ */
+
+#ifndef _SPARC64_PCI_SCHIZOREG_H_
+#define	_SPARC64_PCI_SCHIZOREG_H_
+
+#define	STX_NINTR			5	/* 4 via OFW + 1 CDMA */
+#define	SCZ_NREG			3
+#define	TOM_NREG			4
+
+#define	STX_PCI				0
+#define	STX_CTRL			1
+#define	STX_PCICFG			2
+#define	STX_ICON			3
+
+/* PCI configuration and status registers */
+#define	SX_PCI_CFG_ICD			0x00110
+#define	STX_PCI_IOMMU			0x00200
+#define	STX_PCI_IOMMU_CTXFLUSH		0x00218
+#define	STX_PCI_IMAP_BASE		0x01000
+#define	STX_PCI_ICLR_BASE		0x01400
+#define	STX_PCI_INTR_RETRY_TIM		0x01a00
+#define	SCZ_PCI_DMA_SYNC		0x01a08
+#define	TOM_PCI_DMA_SYNC_COMP		0x01a10
+#define	TOMXMS_PCI_DMA_SYNC_PEND	0x01a18
+#define	STX_PCI_CTRL			0x02000
+#define	STX_PCI_AFSR			0x02010
+#define	STX_PCI_AFAR			0x02018
+#define	STX_PCI_DIAG			0x02020
+#define	XMS_PCI_PARITY_DETECT		0x02040
+#define	TOM_PCI_IOC_CSR			0x02248
+#define	TOM_PCI_IOC_TAG			0x02290
+#define	TOM_PCI_IOC_DATA		0x02290
+#define	XMS_PCI_X_ERR_STAT		0x02300
+#define	XMS_PCI_X_DIAG			0x02308
+#define	XMS_PCI_UPPER_RETRY_COUNTER	0x02310
+#define	STX_PCI_STRBUF			0x02800
+#define	STX_PCI_STRBUF_CTXFLUSH		0x02818
+#define	STX_PCI_IOMMU_SVADIAG		0x0a400
+#define	STX_PCI_IOMMU_TLB_CMP_DIAG	0x0a408
+#define	STX_PCI_IOMMU_QUEUE_DIAG	0x0a500
+#define	STX_PCI_IOMMU_TLB_TAG_DIAG	0x0a580
+#define	STX_PCI_IOMMU_TLB_DATA_DIAG	0x0a600
+#define	STX_PCI_IOBIO_DIAG		0x0a808
+#define	STX_PCI_STRBUF_CTXMATCH		0x10000
+
+/* PCI configuration/idle check diagnostic register */
+#define	SX_PCI_CFG_ICD_PCI_2_0_COMPAT	0x0000000000008000ULL
+#define	SX_PCI_CFG_ICD_DMAW_PERR_IEN	0x0000000000004000ULL
+#define	SX_PCI_CFG_ICD_IFC_NOT_IDLE	0x0000000000000010ULL
+#define	SX_PCI_CFG_ICD_MDU_NOT_IDLE	0x0000000000000008ULL
+#define	SX_PCI_CFG_ICD_MMU_NOT_IDLE	0x0000000000000004ULL
+#define	SX_PCI_CFG_ICD_PBM_NOT_IDLE	0x0000000000000002ULL
+#define	SX_PCI_CFG_ICD_STC_NOT_IDLE	0x0000000000000001ULL
+
+/* PCI IOMMU control register */
+#define	TOM_PCI_IOMMU_ERR_BAD_VA	0x0000000010000000ULL
+#define	TOM_PCI_IOMMU_ERR_ILLTSBTBW	0x0000000008000000ULL
+#define	TOM_PCI_IOMMU_ECC_ERR		0x0000000006000000ULL
+#define	TOM_PCI_IOMMU_TIMEOUT_ERR	0x0000000004000000ULL
+#define	TOM_PCI_IOMMU_INVALID_ERR	0x0000000002000000ULL
+#define	TOM_PCI_IOMMU_PROTECTION_ERR	0x0000000000000000ULL
+#define	TOM_PCI_IOMMU_ERRMASK						\
+	(TOM_PCI_IOMMU_PROTECTION_ERR | TOM_PCI_IOMMU_INVALID_ERR |	\
+	TOM_PCI_IOMMU_TIMEOUT_ERR | TOM_PCI_IOMMU_ECC_ERR)
+#define	TOM_PCI_IOMMU_ERR		0x0000000001000000ULL
+
+/* PCI control/status register */
+#define	SCZ_PCI_CTRL_BUS_UNUS		0x8000000000000000ULL
+#define	TOM_PCI_CTRL_DTO_ERR		0x4000000000000000ULL
+#define	TOM_PCI_CTRL_DTO_IEN		0x2000000000000000ULL
+#define	SCZ_PCI_CTRL_ESLCK		0x0008000000000000ULL
+#define	XMS_PCI_CTRL_DMA_WR_PERR	0x0008000000000000ULL
+#define	SCZ_PCI_CTRL_ERRSLOT		0x0007000000000000ULL
+#define	STX_PCI_CTRL_TTO_ERR		0x0000004000000000ULL
+#define	STX_PCI_CTRL_RTRY_ERR		0x0000002000000000ULL
+#define	STX_PCI_CTRL_MMU_ERR		0x0000001000000000ULL
+#define	SCZ_PCI_CTRL_SBH_ERR		0x0000000800000000ULL
+#define	STX_PCI_CTRL_SERR		0x0000000400000000ULL
+#define	SCZ_PCI_CTRL_PCISPD		0x0000000200000000ULL
+#define	XMS_PCI_CTRL_X_MODE		0x0000000100000000ULL
+#define	TOM_PCI_CTRL_PRM		0x0000000040000000ULL
+#define	TOM_PCI_CTRL_PRO		0x0000000020000000ULL
+#define	TOM_PCI_CTRL_PRL		0x0000000010000000ULL
+#define	STX_PCI_CTRL_PTO		0x0000000003000000ULL
+#define	XMS_PCI_CTRL_X_ERRINT_EN	0x0000000000100000ULL
+#define	STX_PCI_CTRL_MMU_IEN		0x0000000000080000ULL
+#define	STX_PCI_CTRL_SBH_IEN		0x0000000000040000ULL
+#define	STX_PCI_CTRL_ERR_IEN		0x0000000000020000ULL
+#define	STX_PCI_CTRL_ARB_PARK		0x0000000000010000ULL
+#define	SCZ_PCI_CTRL_PCIRST		0x0000000000000100ULL
+#define	STX_PCI_CTRL_ARB_MASK		0x00000000000000ffULL
+#define	XMS_PCI_CTRL_XMITS10_ARB_MASK	0x000000000000000fULL
+
+/* PCI asynchronous fault status register */
+#define	STX_PCI_AFSR_P_MA		0x8000000000000000ULL
+#define	STX_PCI_AFSR_P_TA		0x4000000000000000ULL
+#define	STX_PCI_AFSR_P_RTRY		0x2000000000000000ULL
+#define	STX_PCI_AFSR_P_PERR		0x1000000000000000ULL
+#define	STX_PCI_AFSR_P_TTO		0x0800000000000000ULL
+#define	STX_PCI_AFSR_P_UNUS		0x0400000000000000ULL
+#define	STX_PCI_AFSR_S_MA		0x0200000000000000ULL
+#define	STX_PCI_AFSR_S_TA		0x0100000000000000ULL
+#define	STX_PCI_AFSR_S_RTRY		0x0080000000000000ULL
+#define	STX_PCI_AFSR_S_PERR		0x0040000000000000ULL
+#define	STX_PCI_AFSR_S_TTO		0x0020000000000000ULL
+#define	STX_PCI_AFSR_S_UNUS		0x0010000000000000ULL
+#define	STX_PCI_AFSR_DWMASK		0x0000030000000000ULL
+#define	STX_PCI_AFSR_BMASK		0x000000ff00000000ULL
+#define	STX_PCI_AFSR_BLK		0x0000000080000000ULL
+#define	STX_PCI_AFSR_CFG		0x0000000040000000ULL
+#define	STX_PCI_AFSR_MEM		0x0000000020000000ULL
+#define	STX_PCI_AFSR_IO			0x0000000010000000ULL
+
+/* PCI diagnostic register */
+#define	SCZ_PCI_DIAG_BADECC_DIS		0x0000000000000400ULL
+#define	STX_PCI_DIAG_BYPASS_DIS		0x0000000000000200ULL
+#define	STX_PCI_DIAG_TTO_DIS		0x0000000000000100ULL
+#define	SCZ_PCI_DIAG_RTRYARB_DIS	0x0000000000000080ULL
+#define	STX_PCI_DIAG_RETRY_DIS		0x0000000000000040ULL
+#define	STX_PCI_DIAG_INTRSYNC_DIS	0x0000000000000020ULL
+#define	STX_PCI_DIAG_DMAPARITY_INV	0x0000000000000008ULL
+#define	STX_PCI_DIAG_PIODPARITY_INV	0x0000000000000004ULL
+#define	STX_PCI_DIAG_PIOAPARITY_INV	0x0000000000000002ULL
+
+/* Tomatillo I/O cache register */
+#define	TOM_PCI_IOC_PW			0x0000000000080000ULL
+#define	TOM_PCI_IOC_PRM			0x0000000000040000ULL
+#define	TOM_PCI_IOC_PRO			0x0000000000020000ULL
+#define	TOM_PCI_IOC_PRL			0x0000000000010000ULL
+#define	TOM_PCI_IOC_PRM_LEN		0x000000000000c000ULL
+#define	TOM_PCI_IOC_PRM_LEN_SHIFT	14
+#define	TOM_PCI_IOC_PRO_LEN		0x0000000000003000ULL
+#define	TOM_PCI_IOC_PRO_LEN_SHIFT	12
+#define	TOM_PCI_IOC_PRL_LEN		0x0000000000000c00ULL
+#define	TOM_PCI_IOC_PRL_LEN_SHIFT	10
+#define	TOM_PCI_IOC_PREF_OFF		0x0000000000000038ULL
+#define	TOM_PCI_IOC_PREF_OFF_SHIFT	3
+#define	TOM_PCI_IOC_CPRM		0x0000000000000004ULL
+#define	TOM_PCI_IOC_CPRO		0x0000000000000002ULL
+#define	TOM_PCI_IOC_CPRL		0x0000000000000001ULL
+
+/* XMITS PCI-X error status register */
+#define	XMS_PCI_X_ERR_STAT_P_SC_DSCRD	0x8000000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_P_SC_TTO	0x4000000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_P_SDSTAT	0x2000000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_P_SMMU	0x1000000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_P_CDSTAT	0x0800000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_P_CMMU	0x0400000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_S_SC_DSCRD	0x0080000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_S_SC_TTO	0x0040000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_S_SDSTAT	0x0020000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_S_SMMU	0x0010000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_S_CDSTAT	0x0008000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_S_CMMU	0x0004000000000000ULL
+#define	XMS_PCI_X_ERR_STAT_PERR_RCV_IEN	0x0000000400000000ULL
+#define	XMS_PCI_X_ERR_STAT_PERR_RCV	0x0000000200000000ULL
+#define	XMS_PCI_X_ERR_STAT_SERR_ON_PERR	0x0000000100000000ULL
+
+/* XMITS PCI-X diagnostic register */
+#define	XMS_PCI_X_DIAG_DIS_FAIR		0x0000000000080000ULL
+#define	XMS_PCI_X_DIAG_CRCQ_VALID	0x0000000000040000ULL
+#define	XMS_PCI_X_DIAG_SRCQ_ONE		0x0000000000000200ULL
+#define	XMS_PCI_X_DIAG_CRCQ_FLUSH	0x0000000000000100ULL
+#define	XMS_PCI_X_DIAG_BUGCNTL_MASK	0x0000ffff00000000ULL
+#define	XMS_PCI_X_DIAG_BUGCNTL_SHIFT	32
+#define	XMS_PCI_X_DIAG_SRCQ_MASK	0x00000000000000ffULL
+
+/* Controller configuration and status registers */
+/* Note that these are shared on Schizo but per-PBM on Tomatillo. */
+#define	STX_CTRL_BUS_ERRLOG		0x00018
+#define	STX_CTRL_ECCCTRL		0x00020
+#define	STX_CTRL_UE_AFSR		0x00030
+#define	STX_CTRL_UE_AFAR		0x00038
+#define	STX_CTRL_CE_AFSR		0x00040
+#define	STX_CTRL_CE_AFAR		0x00048
+#define	STX_CTRL_PERF			0x07000
+#define	STX_CTRL_PERF_CNT		0x07008
+
+/* Safari/JBus error log register */
+#define	STX_CTRL_BUS_ERRLOG_BADCMD	0x4000000000000000ULL
+#define	SCZ_CTRL_BUS_ERRLOG_SSMDIS	0x2000000000000000ULL
+#define	SCZ_CTRL_BUS_ERRLOG_BADMA	0x1000000000000000ULL
+#define	SCZ_CTRL_BUS_ERRLOG_BADMB	0x0800000000000000ULL
+#define	SCZ_CTRL_BUS_ERRLOG_BADMC	0x0400000000000000ULL
+#define	TOM_CTRL_BUS_ERRLOG_SNOOP_GR	0x0000000000200000ULL
+#define	TOM_CTRL_BUS_ERRLOG_SNOOP_PCI	0x0000000000100000ULL
+#define	TOM_CTRL_BUS_ERRLOG_SNOOP_RD	0x0000000000080000ULL
+#define	TOM_CTRL_BUS_ERRLOG_SNOOP_RDS	0x0000000000020000ULL
+#define	TOM_CTRL_BUS_ERRLOG_SNOOP_RDSA	0x0000000000010000ULL
+#define	TOM_CTRL_BUS_ERRLOG_SNOOP_OWN	0x0000000000008000ULL
+#define	TOM_CTRL_BUS_ERRLOG_SNOOP_RDO	0x0000000000004000ULL
+#define	SCZ_CTRL_BUS_ERRLOG_CPU1PS	0x0000000000002000ULL
+#define	TOM_CTRL_BUS_ERRLOG_WDATA_PERR	0x0000000000002000ULL
+#define	SCZ_CTRL_BUS_ERRLOG_CPU1PB	0x0000000000001000ULL
+#define	TOM_CTRL_BUS_ERRLOG_CTRL_PERR	0x0000000000001000ULL
+#define	SCZ_CTRL_BUS_ERRLOG_CPU0PS	0x0000000000000800ULL
+#define	TOM_CTRL_BUS_ERRLOG_SNOOP_ERR	0x0000000000000800ULL
+#define	SCZ_CTRL_BUS_ERRLOG_CPU0PB	0x0000000000000400ULL
+#define	TOM_CTRL_BUS_ERRLOG_JBUS_ILL_B	0x0000000000000400ULL
+#define	SCZ_CTRL_BUS_ERRLOG_CIQTO	0x0000000000000200ULL
+#define	SCZ_CTRL_BUS_ERRLOG_LPQTO	0x0000000000000100ULL
+#define	TOM_CTRL_BUS_ERRLOG_JBUS_ILL_C	0x0000000000000100ULL
+#define	SCZ_CTRL_BUS_ERRLOG_SFPQTO	0x0000000000000080ULL
+#define	SCZ_CTRL_BUS_ERRLOG_UFPQTO	0x0000000000000040ULL
+#define	TOM_CTRL_BUS_ERRLOG_RD_PERR	0x0000000000000040ULL
+#define	STX_CTRL_BUS_ERRLOG_APERR	0x0000000000000020ULL
+#define	STX_CTRL_BUS_ERRLOG_UNMAP	0x0000000000000010ULL
+#define	STX_CTRL_BUS_ERRLOG_BUSERR	0x0000000000000004ULL
+#define	STX_CTRL_BUS_ERRLOG_TIMEOUT	0x0000000000000002ULL
+#define	SCZ_CTRL_BUS_ERRLOG_ILL		0x0000000000000001ULL
+
+/* ECC control register */
+#define	STX_CTRL_ECCCTRL_EE		0x8000000000000000ULL
+#define	STX_CTRL_ECCCTRL_UE		0x4000000000000000ULL
+#define	STX_CTRL_ECCCTRL_CE		0x2000000000000000ULL
+
+/* Uncorrectable error asynchronous fault status register */
+#define	STX_CTRL_UE_AFSR_P_PIO		0x8000000000000000ULL
+#define	STX_CTRL_UE_AFSR_P_DRD		0x4000000000000000ULL
+#define	STX_CTRL_UE_AFSR_P_DWR		0x2000000000000000ULL
+#define	STX_CTRL_UE_AFSR_S_PIO		0x1000000000000000ULL
+#define	STX_CTRL_UE_AFSR_S_DRD		0x0800000000000000ULL
+#define	STX_CTRL_UE_AFSR_S_DWR		0x0400000000000000ULL
+#define	STX_CTRL_UE_AFSR_ERRPNDG	0x0300000000000000ULL
+#define	STX_CTRL_UE_AFSR_BMASK		0x000003ff00000000ULL
+#define	STX_CTRL_UE_AFSR_QOFF		0x00000000c0000000ULL
+#define	STX_CTRL_UE_AFSR_AID		0x000000001f000000ULL
+#define	STX_CTRL_UE_AFSR_PARTIAL	0x0000000000800000ULL
+#define	STX_CTRL_UE_AFSR_OWNEDIN	0x0000000000400000ULL
+#define	STX_CTRL_UE_AFSR_MTAGSYND	0x00000000000f0000ULL
+#define	STX_CTRL_UE_AFSR_MTAG		0x000000000000e000ULL
+#define	STX_CTRL_UE_AFSR_ECCSYND	0x00000000000001ffULL
+
+/* Correctable error asynchronous fault status register */
+#define	STX_CTRL_CE_AFSR_P_PIO		0x8000000000000000ULL
+#define	STX_CTRL_CE_AFSR_P_DRD		0x4000000000000000ULL
+#define	STX_CTRL_CE_AFSR_P_DWR		0x2000000000000000ULL
+#define	STX_CTRL_CE_AFSR_S_PIO		0x1000000000000000ULL
+#define	STX_CTRL_CE_AFSR_S_DRD		0x0800000000000000ULL
+#define	STX_CTRL_CE_AFSR_S_DWR		0x0400000000000000ULL
+#define	STX_CTRL_CE_AFSR_ERRPNDG	0x0300000000000000ULL
+#define	STX_CTRL_CE_AFSR_BMASK		0x000003ff00000000ULL
+#define	STX_CTRL_CE_AFSR_QOFF		0x00000000c0000000ULL
+#define	STX_CTRL_CE_AFSR_AID		0x000000001f000000ULL
+#define	STX_CTRL_CE_AFSR_PARTIAL	0x0000000000800000ULL
+#define	STX_CTRL_CE_AFSR_OWNEDIN	0x0000000000400000ULL
+#define	STX_CTRL_CE_AFSR_MTAGSYND	0x00000000000f0000ULL
+#define	STX_CTRL_CE_AFSR_MTAG		0x000000000000e000ULL
+#define	STX_CTRL_CE_AFSR_ECCSYND	0x00000000000001ffULL
+
+/*
+ * Safari/JBus performance control register
+ * NB: For Tomatillo only events 0x00 through 0x08 are documented as
+ * implemented.
+ */
+#define	SCZ_CTRL_PERF_ZDATA_OUT		0x0000000000000016ULL
+#define	SCZ_CTRL_PERF_ZDATA_IN		0x0000000000000015ULL
+#define	SCZ_CTRL_PERF_ORQFULL		0x0000000000000014ULL
+#define	SCZ_CTRL_PERF_DVMA_WR		0x0000000000000013ULL
+#define	SCZ_CTRL_PERF_DVMA_RD		0x0000000000000012ULL
+#define	SCZ_CTRL_PERF_CYCPSESYS		0x0000000000000011ULL
+#define	STX_CTRL_PERF_PCI_B		0x000000000000000fULL
+#define	STX_CTRL_PERF_PCI_A		0x000000000000000eULL
+#define	STX_CTRL_PERF_UPA		0x000000000000000dULL
+#define	STX_CTRL_PERF_PIOINTRNL		0x000000000000000cULL
+#define	TOM_CTRL_PERF_WRI_WRIS		0x000000000000000bULL
+#define	STX_CTRL_PERF_INTRS		0x000000000000000aULL
+#define	STX_CTRL_PERF_PRTLWRMRGBUF	0x0000000000000009ULL
+#define	STX_CTRL_PERF_FGN_IO_HITS	0x0000000000000008ULL
+#define	STX_CTRL_PERF_FGN_IO_TRNS	0x0000000000000007ULL
+#define	STX_CTRL_PERF_OWN_CHRNT_HITS	0x0000000000000006ULL
+#define	STX_CTRL_PERF_OWN_CHRNT_TRNS	0x0000000000000005ULL
+#define	SCZ_CTRL_PERF_FGN_CHRNT_HITS	0x0000000000000004ULL
+#define	STX_CTRL_PERF_FGN_CHRNT_TRNS	0x0000000000000003ULL
+#define	STX_CTRL_PERF_CYCLES_PAUSE	0x0000000000000002ULL
+#define	STX_CTRL_PERF_BUSCYC		0x0000000000000001ULL
+#define	STX_CTRL_PERF_DIS		0x0000000000000000ULL
+#define	STX_CTRL_PERF_CNT1_SHIFT	11
+#define	STX_CTRL_PERF_CNT0_SHIFT	4
+
+/* Safari/JBus performance counter register */
+#define	STX_CTRL_PERF_CNT_MASK	0x00000000ffffffffULL
+#define	STX_CTRL_PERF_CNT_CNT1_SHIFT	32
+#define	STX_CTRL_PERF_CNT_CNT0_SHIFT	0
+
+/* INO defines */
+#define	STX_FB0_INO			0x2a	/* FB0 int. shared w/ UPA64s */
+#define	STX_FB1_INO			0x2b	/* FB1 int. shared w/ UPA64s */
+#define	STX_UE_INO			0x30	/* uncorrectable error */
+#define	STX_CE_INO			0x31	/* correctable error */
+#define	STX_PCIERR_A_INO		0x32	/* PCI bus A error */
+#define	STX_PCIERR_B_INO		0x33	/* PCI bus B error */
+#define	STX_BUS_INO			0x34	/* Safari/JBus error */
+#define	STX_CDMA_A_INO			0x35	/* PCI bus A CDMA */
+#define	STX_CDMA_B_INO			0x36	/* PCI bus B CDMA */
+#define	STX_MAX_INO			0x37
+
+/* Device space defines */
+#define	STX_CONF_SIZE			0x1000000
+#define	STX_CONF_BUS_SHIFT		16
+#define	STX_CONF_DEV_SHIFT		11
+#define	STX_CONF_FUNC_SHIFT		8
+#define	STX_CONF_REG_SHIFT		0
+#define	STX_IO_SIZE			0x1000000
+#define	STX_MEM_SIZE			0x100000000
+
+#define	STX_CONF_OFF(bus, slot, func, reg)				\
+	(((bus) << STX_CONF_BUS_SHIFT) |				\
+	((slot) << STX_CONF_DEV_SHIFT) |				\
+	((func) << STX_CONF_FUNC_SHIFT) |				\
+	((reg) << STX_CONF_REG_SHIFT))
+
+/* Definitions for the Schizo/Tomatillo configuration space */
+#define	STX_CS_DEVICE			0	/* bridge CS device number */
+#define	STX_CS_FUNC			0	/* brdige CS function number */
+
+/* Non-Standard registers in the configration space */
+/*
+ * NB: For Tomatillo the secondary and subordinate bus number registers
+ * apparently are read-only although documented otherwise; writing to
+ * them just triggers a PCI bus error interrupt or has no effect at best.
+ */
+#define	STX_CSR_SECBUS			0x40	/* secondary bus number */
+#define	STX_CSR_SUBBUS			0x41	/* subordinate bus number */
+
+/* Width of the physical addresses the IOMMU translates to */
+#define	STX_IOMMU_BITS			43
+
+#endif /* !_SPARC64_PCI_SCHIZOREG_H_ */


Property changes on: trunk/sys/sparc64/pci/schizoreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/pci/schizovar.h
===================================================================
--- trunk/sys/sparc64/pci/schizovar.h	                        (rev 0)
+++ trunk/sys/sparc64/pci/schizovar.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,91 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 by Marius Strobl <marius at 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, this list of conditions, and the following disclaimer,
+ *    without modification, immediately at the beginning of the file.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/pci/schizovar.h 292789 2015-12-27 19:37:47Z marius $
+ */
+
+#ifndef _SPARC64_PCI_SCHIZOVAR_H_
+#define	_SPARC64_PCI_SCHIZOVAR_H_
+
+struct schizo_softc;
+
+struct schizo_iommu_state {
+	struct iommu_state	sis_is;
+	struct schizo_softc	*sis_sc;
+};
+
+struct schizo_softc {
+	/*
+	 * This is here so that we can hook up the common bus interface
+	 * methods in ofw_pci.c directly.
+	 */
+	struct ofw_pci_softc		sc_ops;
+
+	struct schizo_iommu_state	sc_is;
+	struct bus_dma_methods          sc_dma_methods;
+
+	struct mtx			sc_sync_mtx;
+	uint64_t			sc_sync_val;
+
+	struct mtx			*sc_mtx;
+
+	struct resource			*sc_mem_res[TOM_NREG];
+	struct resource			*sc_irq_res[STX_NINTR];
+	void				*sc_ihand[STX_NINTR];
+
+	SLIST_ENTRY(schizo_softc)	sc_link;
+
+	device_t			sc_dev;
+
+	u_int				sc_mode;
+#define	SCHIZO_MODE_SCZ			0
+#define	SCHIZO_MODE_TOM			1
+#define	SCHIZO_MODE_XMS			2
+
+	u_int				sc_flags;
+#define	SCHIZO_FLAGS_BSWAR		(1 << 0)
+#define	SCHIZO_FLAGS_XMODE		(1 << 1)
+
+	bus_addr_t			sc_cdma_map;
+	bus_addr_t			sc_cdma_clr;
+	uint32_t			sc_cdma_vec;
+	uint32_t			sc_cdma_state;
+#define	SCHIZO_CDMA_STATE_IDLE		(1 << 0)
+#define	SCHIZO_CDMA_STATE_PENDING	(1 << 1)
+#define	SCHIZO_CDMA_STATE_RECEIVED	(1 << 2)
+
+	u_int				sc_half;
+	uint32_t			sc_ign;
+	uint32_t			sc_ver;
+	uint32_t			sc_mrev;
+
+	uint32_t			sc_stats_dma_ce;
+	uint32_t			sc_stats_pci_non_fatal;
+};
+
+#endif /* !_SPARC64_PCI_SCHIZOVAR_H_ */


Property changes on: trunk/sys/sparc64/pci/schizovar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sbus/dma_sbus.c
===================================================================
--- trunk/sys/sparc64/sbus/dma_sbus.c	                        (rev 0)
+++ trunk/sys/sparc64/sbus/dma_sbus.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,416 @@
+/* $MidnightBSD$ */
+/*	$OpenBSD: dma_sbus.c,v 1.16 2008/06/26 05:42:18 ray Exp $	*/
+/*	$NetBSD: dma_sbus.c,v 1.32 2008/04/28 20:23:57 martin Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 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) 1994 Peter Galbavy.  All rights reserved.
+ * Copyright (c) 2005 Marius Strobl <marius at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sbus/dma_sbus.c 227848 2011-11-22 21:55:40Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/bus_common.h>
+#include <machine/resource.h>
+
+#include <sparc64/sbus/lsi64854reg.h>
+#include <sparc64/sbus/lsi64854var.h>
+#include <sparc64/sbus/ofw_sbus.h>
+#include <sparc64/sbus/sbusreg.h>
+#include <sparc64/sbus/sbusvar.h>
+
+struct dma_devinfo {
+	struct ofw_bus_devinfo	ddi_obdinfo;
+	struct resource_list	ddi_rl;
+};
+
+struct dma_softc {
+	struct lsi64854_softc	sc_lsi64854;	/* base device */
+	int			sc_ign;
+	int			sc_slot;
+};
+
+static devclass_t dma_devclass;
+
+static device_probe_t dma_probe;
+static device_attach_t dma_attach;
+static bus_print_child_t dma_print_child;
+static bus_probe_nomatch_t dma_probe_nomatch;
+static bus_get_resource_list_t dma_get_resource_list;
+static ofw_bus_get_devinfo_t dma_get_devinfo;
+
+static struct dma_devinfo *dma_setup_dinfo(device_t, struct dma_softc *,
+    phandle_t);
+static void dma_destroy_dinfo(struct dma_devinfo *);
+static int dma_print_res(struct dma_devinfo *);
+
+static device_method_t dma_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		dma_probe),
+	DEVMETHOD(device_attach,	dma_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	dma_print_child),
+	DEVMETHOD(bus_probe_nomatch,	dma_probe_nomatch),
+	DEVMETHOD(bus_alloc_resource,	bus_generic_rl_alloc_resource),
+	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	bus_generic_adjust_resource),
+	DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
+	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	DEVMETHOD(bus_get_resource_list, dma_get_resource_list),
+	DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	dma_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	DEVMETHOD_END
+};
+
+static driver_t dma_driver = {
+	"dma",
+	dma_methods,
+	sizeof(struct dma_softc),
+};
+
+/*
+ * The probe order is handled by sbus(4) as we don't want the variants
+ * with children to be attached earlier than the stand-alone controllers
+ * in order to generally preserve the OFW device tree order.
+ */
+EARLY_DRIVER_MODULE(dma, sbus, dma_driver, dma_devclass, 0, 0,
+    BUS_PASS_DEFAULT);
+MODULE_DEPEND(dma, sbus, 1, 1, 1);
+MODULE_VERSION(dma, 1);
+
+static int
+dma_probe(device_t dev)
+{
+	const char *name;
+
+	name = ofw_bus_get_name(dev);
+	if (strcmp(name, "espdma") == 0 || strcmp(name, "dma") == 0 ||
+	    strcmp(name, "ledma") == 0) {
+		device_set_desc_copy(dev, name);
+		return (0);
+	}
+	return (ENXIO);
+}
+
+static int
+dma_attach(device_t dev)
+{
+	struct dma_softc *dsc;
+	struct lsi64854_softc *lsc;
+	struct dma_devinfo *ddi;
+	device_t cdev;
+	const char *name;
+	char *cabletype;
+	uint32_t csr;
+	phandle_t child, node;
+	int error, i;
+
+	dsc = device_get_softc(dev);
+	lsc = &dsc->sc_lsi64854;
+
+	name = ofw_bus_get_name(dev);
+	node = ofw_bus_get_node(dev);
+	dsc->sc_ign = sbus_get_ign(dev);
+	dsc->sc_slot = sbus_get_slot(dev);
+
+	i = 0;
+	lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i,
+	    RF_ACTIVE);
+	if (lsc->sc_res == NULL) {
+		device_printf(dev, "cannot allocate resources\n");
+		return (ENXIO);
+	}
+
+	if (strcmp(name, "espdma") == 0 || strcmp(name, "dma") == 0)
+		lsc->sc_channel = L64854_CHANNEL_SCSI;
+	else if (strcmp(name, "ledma") == 0) {
+		/*
+		 * Check to see which cable type is currently active and
+		 * set the appropriate bit in the ledma csr so that it
+		 * gets used. If we didn't netboot, the PROM won't have
+		 * the "cable-selection" property; default to TP and then
+		 * the user can change it via a "media" option to ifconfig.
+		 */
+		csr = L64854_GCSR(lsc);
+		if ((OF_getprop_alloc(node, "cable-selection", 1,
+		    (void **)&cabletype)) == -1) {
+			/* assume TP if nothing there */
+			csr |= E_TP_AUI;
+		} else {
+			if (strcmp(cabletype, "aui") == 0)
+				csr &= ~E_TP_AUI;
+			else
+				csr |= E_TP_AUI;
+			free(cabletype, M_OFWPROP);
+		}
+		L64854_SCSR(lsc, csr);
+		DELAY(20000);	/* manual says we need a 20ms delay */
+		lsc->sc_channel = L64854_CHANNEL_ENET;
+	} else {
+		device_printf(dev, "unsupported DMA channel\n");
+		error = ENXIO;
+		goto fail_lres;
+	}
+
+	error = bus_dma_tag_create(
+	    bus_get_dma_tag(dev),	/* parent */
+	    1, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    BUS_SPACE_MAXSIZE,		/* maxsize */
+	    BUS_SPACE_UNRESTRICTED,	/* nsegments */
+	    BUS_SPACE_MAXSIZE,		/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* no locking */
+	    &lsc->sc_parent_dmat);
+	if (error != 0) {
+		device_printf(dev, "cannot allocate parent DMA tag\n");
+		goto fail_lres;
+	}
+
+	i = sbus_get_burstsz(dev);
+	lsc->sc_burst = (i & SBUS_BURST_32) ? 32 :
+	    (i & SBUS_BURST_16) ? 16 : 0;
+	lsc->sc_dev = dev;
+
+	/* Attach children. */
+	i = 0;
+	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+		if ((ddi = dma_setup_dinfo(dev, dsc, child)) == NULL)
+			continue;
+		if (i != 0) {
+			device_printf(dev,
+			    "<%s>: only one child per DMA channel supported\n",
+			    ddi->ddi_obdinfo.obd_name);
+			dma_destroy_dinfo(ddi);
+			continue;
+		}
+		if ((cdev = device_add_child(dev, NULL, -1)) == NULL) {
+			device_printf(dev, "<%s>: device_add_child failed\n",
+			    ddi->ddi_obdinfo.obd_name);
+			dma_destroy_dinfo(ddi);
+			continue;
+		}
+		device_set_ivars(cdev, ddi);
+		i++;
+	}
+	return (bus_generic_attach(dev));
+
+ fail_lres:
+	bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res),
+	    lsc->sc_res);
+	return (error);
+}
+
+static struct dma_devinfo *
+dma_setup_dinfo(device_t dev, struct dma_softc *dsc, phandle_t node)
+{
+	struct dma_devinfo *ddi;
+	struct sbus_regs *reg;
+	uint32_t base, iv, *intr;
+	int i, nreg, nintr, slot, rslot;
+
+	ddi = malloc(sizeof(*ddi), M_DEVBUF, M_WAITOK | M_ZERO);
+	if (ofw_bus_gen_setup_devinfo(&ddi->ddi_obdinfo, node) != 0) {
+		free(ddi, M_DEVBUF);
+		return (NULL);
+	}
+	resource_list_init(&ddi->ddi_rl);
+	slot = -1;
+	nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
+	if (nreg == -1) {
+		device_printf(dev, "<%s>: incomplete\n",
+		    ddi->ddi_obdinfo.obd_name);
+		goto fail;
+	}
+	for (i = 0; i < nreg; i++) {
+		base = reg[i].sbr_offset;
+		if (SBUS_ABS(base)) {
+			rslot = SBUS_ABS_TO_SLOT(base);
+			base = SBUS_ABS_TO_OFFSET(base);
+		} else
+			rslot = reg[i].sbr_slot;
+		if (slot != -1 && slot != rslot) {
+			device_printf(dev, "<%s>: multiple slots\n",
+			    ddi->ddi_obdinfo.obd_name);
+			free(reg, M_OFWPROP);
+			goto fail;
+		}
+		slot = rslot;
+
+		resource_list_add(&ddi->ddi_rl, SYS_RES_MEMORY, i, base,
+		    base + reg[i].sbr_size, reg[i].sbr_size);
+	}
+	free(reg, M_OFWPROP);
+	if (slot != dsc->sc_slot) {
+		device_printf(dev, "<%s>: parent and child slot do not match\n",
+		    ddi->ddi_obdinfo.obd_name);
+		goto fail;
+	}
+
+	/*
+	 * The `interrupts' property contains the SBus interrupt level.
+	 */
+	nintr = OF_getprop_alloc(node, "interrupts", sizeof(*intr),
+	    (void **)&intr);
+	if (nintr != -1) {
+		for (i = 0; i < nintr; i++) {
+			iv = intr[i];
+			/*
+			 * SBus card devices need the slot number encoded into
+			 * the vector as this is generally not done.
+			 */
+			if ((iv & INTMAP_OBIO_MASK) == 0)
+				iv |= slot << 3;
+			/* Set the IGN as appropriate. */
+			iv |= dsc->sc_ign << INTMAP_IGN_SHIFT;
+			resource_list_add(&ddi->ddi_rl, SYS_RES_IRQ, i,
+			    iv, iv, 1);
+		}
+		free(intr, M_OFWPROP);
+	}
+	return (ddi);
+
+ fail:
+	dma_destroy_dinfo(ddi);
+	return (NULL);
+}
+
+static void
+dma_destroy_dinfo(struct dma_devinfo *dinfo)
+{
+
+	resource_list_free(&dinfo->ddi_rl);
+	ofw_bus_gen_destroy_devinfo(&dinfo->ddi_obdinfo);
+	free(dinfo, M_DEVBUF);
+}
+
+static int
+dma_print_child(device_t dev, device_t child)
+{
+	int rv;
+
+	rv = bus_print_child_header(dev, child);
+	rv += dma_print_res(device_get_ivars(child));
+	rv += bus_print_child_footer(dev, child);
+	return (rv);
+}
+
+static void
+dma_probe_nomatch(device_t dev, device_t child)
+{
+	const char *type;
+
+	device_printf(dev, "<%s>", ofw_bus_get_name(child));
+	dma_print_res(device_get_ivars(child));
+	type = ofw_bus_get_type(child);
+	printf(" type %s (no driver attached)\n",
+	    type != NULL ? type : "unknown");
+}
+
+static struct resource_list *
+dma_get_resource_list(device_t dev, device_t child)
+{
+	struct dma_devinfo *ddi;
+
+	ddi = device_get_ivars(child);
+	return (&ddi->ddi_rl);
+}
+
+static const struct ofw_bus_devinfo *
+dma_get_devinfo(device_t bus, device_t child)
+{
+	struct dma_devinfo *ddi;
+
+	ddi = device_get_ivars(child);
+	return (&ddi->ddi_obdinfo);
+}
+
+static int
+dma_print_res(struct dma_devinfo *ddi)
+{
+	int rv;
+
+	rv = 0;
+	rv += resource_list_print_type(&ddi->ddi_rl, "mem", SYS_RES_MEMORY,
+	    "%#lx");
+	rv += resource_list_print_type(&ddi->ddi_rl, "irq", SYS_RES_IRQ, "%ld");
+	return (rv);
+}


Property changes on: trunk/sys/sparc64/sbus/dma_sbus.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sbus/lsi64854.c
===================================================================
--- trunk/sys/sparc64/sbus/lsi64854.c	                        (rev 0)
+++ trunk/sys/sparc64/sbus/lsi64854.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,763 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Scott Long
+ * 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.
+ *
+ */
+
+/*	$NetBSD: lsi64854.c,v 1.33 2008/04/28 20:23:50 martin Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sbus/lsi64854.c 227578 2011-11-16 18:42:43Z pjd $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+#include <cam/scsi/scsi_all.h>
+
+#include <sparc64/sbus/lsi64854reg.h>
+#include <sparc64/sbus/lsi64854var.h>
+
+#include <dev/esp/ncr53c9xreg.h>
+#include <dev/esp/ncr53c9xvar.h>
+
+#ifdef DEBUG
+#define LDB_SCSI	1
+#define LDB_ENET	2
+#define LDB_PP		4
+#define LDB_ANY		0xff
+int lsi64854debug = 0;
+#define DPRINTF(a,x)							\
+	do {								\
+		if ((lsi64854debug & (a)) != 0)				\
+			printf x;					\
+	} while (/* CONSTCOND */0)
+#else
+#define DPRINTF(a,x)
+#endif
+
+/*
+ * The rules say we cannot transfer more than the limit of this DMA chip (64k
+ * for old and 16Mb for new), and we cannot cross a 16Mb boundary.
+ */
+#define MAX_DMA_SZ	(64 * 1024)
+#define BOUNDARY	(16 * 1024 * 1024)
+
+static void	lsi64854_reset(struct lsi64854_softc *);
+static void	lsi64854_map_scsi(void *, bus_dma_segment_t *, int, int);
+static int	lsi64854_setup(struct lsi64854_softc *, void **, size_t *,
+		    int, size_t *);
+static int	lsi64854_scsi_intr(void *);
+static int	lsi64854_enet_intr(void *);
+static int	lsi64854_setup_pp(struct lsi64854_softc *, void **,
+		    size_t *, int, size_t *);
+static int	lsi64854_pp_intr(void *);
+
+/*
+ * Finish attaching this DMA device.
+ * Front-end must fill in these fields:
+ *	sc_res
+ *	sc_burst
+ *	sc_channel (one of SCSI, ENET, PP)
+ *	sc_client (one of SCSI, ENET, PP `soft_c' pointers)
+ */
+int
+lsi64854_attach(struct lsi64854_softc *sc)
+{
+	bus_dma_lock_t *lockfunc;
+	struct ncr53c9x_softc *nsc;
+	void *lockfuncarg;
+	uint32_t csr;
+	int error;
+
+	lockfunc = NULL;
+	lockfuncarg = NULL;
+	sc->sc_maxdmasize = MAX_DMA_SZ;
+
+	switch (sc->sc_channel) {
+	case L64854_CHANNEL_SCSI:
+		nsc = sc->sc_client;
+		if (NCR_LOCK_INITIALIZED(nsc) == 0) {
+			device_printf(sc->sc_dev, "mutex not initialized\n");
+			return (ENXIO);
+		}
+		lockfunc = busdma_lock_mutex;
+		lockfuncarg = &nsc->sc_lock;
+		sc->sc_maxdmasize = nsc->sc_maxxfer;
+		sc->intr = lsi64854_scsi_intr;
+		sc->setup = lsi64854_setup;
+		break;
+	case L64854_CHANNEL_ENET:
+		sc->intr = lsi64854_enet_intr;
+		break;
+	case L64854_CHANNEL_PP:
+		sc->intr = lsi64854_pp_intr;
+		sc->setup = lsi64854_setup_pp;
+		break;
+	default:
+		device_printf(sc->sc_dev, "unknown channel\n");
+	}
+	sc->reset = lsi64854_reset;
+
+	if (sc->setup != NULL) {
+		error = bus_dma_tag_create(
+		    sc->sc_parent_dmat,		/* parent */
+		    1, BOUNDARY,		/* alignment, boundary */
+		    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+		    BUS_SPACE_MAXADDR,		/* highaddr */
+		    NULL, NULL,			/* filter, filterarg */
+		    sc->sc_maxdmasize,		/* maxsize */
+		    1,				/* nsegments */
+		    sc->sc_maxdmasize,		/* maxsegsize */
+		    BUS_DMA_ALLOCNOW,		/* flags */
+		    lockfunc, lockfuncarg,	/* lockfunc, lockfuncarg */
+		    &sc->sc_buffer_dmat);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "cannot allocate buffer DMA tag\n");
+			return (error);
+		}
+
+		error = bus_dmamap_create(sc->sc_buffer_dmat, 0,
+		    &sc->sc_dmamap);
+		if (error != 0) {
+			device_printf(sc->sc_dev, "DMA map create failed\n");
+			bus_dma_tag_destroy(sc->sc_buffer_dmat);
+			return (error);
+		}
+	}
+
+	csr = L64854_GCSR(sc);
+	sc->sc_rev = csr & L64854_DEVID;
+	if (sc->sc_rev == DMAREV_HME)
+		return (0);
+	device_printf(sc->sc_dev, "DMA rev. ");
+	switch (sc->sc_rev) {
+	case DMAREV_0:
+		printf("0");
+		break;
+	case DMAREV_ESC:
+		printf("ESC");
+		break;
+	case DMAREV_1:
+		printf("1");
+		break;
+	case DMAREV_PLUS:
+		printf("1+");
+		break;
+	case DMAREV_2:
+		printf("2");
+		break;
+	default:
+		printf("unknown (0x%x)", sc->sc_rev);
+	}
+
+	DPRINTF(LDB_ANY, (", burst 0x%x, csr 0x%x", sc->sc_burst, csr));
+	printf("\n");
+
+	return (0);
+}
+
+int
+lsi64854_detach(struct lsi64854_softc *sc)
+{
+
+	if (sc->setup != NULL) {
+		bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
+		    (L64854_GCSR(sc) & L64854_WRITE) != 0 ?
+		    BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+		bus_dmamap_unload(sc->sc_buffer_dmat, sc->sc_dmamap);
+		bus_dmamap_destroy(sc->sc_buffer_dmat, sc->sc_dmamap);
+		bus_dma_tag_destroy(sc->sc_buffer_dmat);
+	}
+
+	return (0);
+}
+
+/*
+ * DMAWAIT waits while condition is true.
+ */
+#define DMAWAIT(SC, COND, MSG, DONTPANIC) do if (COND) {		\
+	int count = 500000;						\
+	while ((COND) && --count > 0) DELAY(1);				\
+	if (count == 0) {						\
+		printf("%s: line %d: CSR = 0x%lx\n", __FILE__, __LINE__, \
+			(u_long)L64854_GCSR(SC));			\
+		if (DONTPANIC)						\
+			printf(MSG);					\
+		else							\
+			panic(MSG);					\
+	}								\
+} while (/* CONSTCOND */0)
+
+#define DMA_DRAIN(sc, dontpanic) do {					\
+	uint32_t csr;							\
+	/*								\
+	 * DMA rev0 & rev1: we are not allowed to touch the DMA "flush"	\
+	 *     and "drain" bits while it is still thinking about a	\
+	 *     request.							\
+	 * other revs: D_ESC_R_PEND bit reads as 0			\
+	 */								\
+	DMAWAIT(sc, L64854_GCSR(sc) & D_ESC_R_PEND, "R_PEND", dontpanic);\
+	if (sc->sc_rev != DMAREV_HME) {					\
+		/*							\
+		 * Select drain bit based on revision			\
+		 * also clears errors and D_TC flag			\
+		 */							\
+		csr = L64854_GCSR(sc);					\
+		if (sc->sc_rev == DMAREV_1 || sc->sc_rev == DMAREV_0)	\
+			csr |= D_ESC_DRAIN;				\
+		else							\
+			csr |= L64854_INVALIDATE;			\
+									\
+		L64854_SCSR(sc, csr);					\
+	}								\
+	/*								\
+	 * Wait for draining to finish					\
+	 * rev0 & rev1 call this PACKCNT				\
+	 */								\
+	DMAWAIT(sc, L64854_GCSR(sc) & L64854_DRAINING, "DRAINING",	\
+	    dontpanic);							\
+} while (/* CONSTCOND */0)
+
+#define DMA_FLUSH(sc, dontpanic) do {					\
+	uint32_t csr;							\
+	/*								\
+	 * DMA rev0 & rev1: we are not allowed to touch the DMA "flush"	\
+	 *     and "drain" bits while it is still thinking about a	\
+	 *     request.							\
+	 * other revs: D_ESC_R_PEND bit reads as 0			\
+	 */								\
+	DMAWAIT(sc, L64854_GCSR(sc) & D_ESC_R_PEND, "R_PEND", dontpanic);\
+	csr = L64854_GCSR(sc);					\
+	csr &= ~(L64854_WRITE|L64854_EN_DMA); /* no-ops on ENET */	\
+	csr |= L64854_INVALIDATE;	 	/* XXX FAS ? */		\
+	L64854_SCSR(sc, csr);						\
+} while (/* CONSTCOND */0)
+
+static void
+lsi64854_reset(struct lsi64854_softc *sc)
+{
+	bus_dma_tag_t dmat;
+	bus_dmamap_t dmam;
+	uint32_t csr;
+
+	DMA_FLUSH(sc, 1);
+	csr = L64854_GCSR(sc);
+
+	DPRINTF(LDB_ANY, ("%s: csr 0x%x\n", __func__, csr));
+
+	if (sc->sc_dmasize != 0) {
+		dmat = sc->sc_buffer_dmat;
+		dmam = sc->sc_dmamap;
+		bus_dmamap_sync(dmat, dmam, (csr & D_WRITE) != 0 ?
+		    BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+		bus_dmamap_unload(dmat, dmam);
+	}
+
+	if (sc->sc_rev == DMAREV_HME)
+		L64854_SCSR(sc, csr | D_HW_RESET_FAS366);
+
+	csr |= L64854_RESET;		/* reset DMA */
+	L64854_SCSR(sc, csr);
+	DELAY(200);			/* > 10 Sbus clocks(?) */
+
+	/*DMAWAIT1(sc); why was this here? */
+	csr = L64854_GCSR(sc);
+	csr &= ~L64854_RESET;		/* de-assert reset line */
+	L64854_SCSR(sc, csr);
+	DELAY(5);			/* allow a few ticks to settle */
+
+	csr = L64854_GCSR(sc);
+	csr |= L64854_INT_EN;		/* enable interrupts */
+	if (sc->sc_rev > DMAREV_1 && sc->sc_channel == L64854_CHANNEL_SCSI) {
+		if (sc->sc_rev == DMAREV_HME)
+			csr |= D_TWO_CYCLE;
+		else
+			csr |= D_FASTER;
+	}
+
+	/* Set burst */
+	switch (sc->sc_rev) {
+	case DMAREV_HME:
+	case DMAREV_2:
+		csr &= ~L64854_BURST_SIZE;
+		if (sc->sc_burst == 32)
+			csr |= L64854_BURST_32;
+		else if (sc->sc_burst == 16)
+			csr |= L64854_BURST_16;
+		else
+			csr |= L64854_BURST_0;
+		break;
+	case DMAREV_ESC:
+		csr |= D_ESC_AUTODRAIN;	/* Auto-drain */
+		if (sc->sc_burst == 32)
+			csr &= ~D_ESC_BURST;
+		else
+			csr |= D_ESC_BURST;
+		break;
+	default:
+		break;
+	}
+	L64854_SCSR(sc, csr);
+
+	if (sc->sc_rev == DMAREV_HME) {
+		bus_write_4(sc->sc_res, L64854_REG_ADDR, 0);
+		sc->sc_dmactl = csr;
+	}
+	sc->sc_active = 0;
+
+	DPRINTF(LDB_ANY, ("%s: done, csr 0x%x\n", __func__, csr));
+}
+
+static void
+lsi64854_map_scsi(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+	struct lsi64854_softc *sc;
+
+	sc = (struct lsi64854_softc *)arg;
+
+	if (error != 0)
+		return;
+	if (nseg != 1)
+		panic("%s: cannot map %d segments\n", __func__, nseg);
+
+	bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
+	    sc->sc_datain != 0 ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+	bus_write_4(sc->sc_res, L64854_REG_ADDR, segs[0].ds_addr);
+}
+
+/*
+ * setup a DMA transfer
+ */
+static int
+lsi64854_setup(struct lsi64854_softc *sc, void **addr, size_t *len,
+    int datain, size_t *dmasize)
+{
+	long bcnt;
+	int error;
+	uint32_t csr;
+
+	DMA_FLUSH(sc, 0);
+
+#if 0
+	DMACSR(sc) &= ~D_INT_EN;
+#endif
+	sc->sc_dmaaddr = addr;
+	sc->sc_dmalen = len;
+	sc->sc_datain = datain;
+
+	KASSERT(*dmasize <= sc->sc_maxdmasize,
+	    ("%s: transfer size %ld too large", __func__, (long)*dmasize));
+
+	sc->sc_dmasize = *dmasize;
+
+	DPRINTF(LDB_ANY, ("%s: dmasize=%ld\n", __func__, (long)*dmasize));
+
+	/*
+	 * XXX what length?
+	 */
+	if (sc->sc_rev == DMAREV_HME) {
+		L64854_SCSR(sc, sc->sc_dmactl | L64854_RESET);
+		L64854_SCSR(sc, sc->sc_dmactl);
+
+		bus_write_4(sc->sc_res, L64854_REG_CNT, *dmasize);
+	}
+
+	/*
+	 * Load the transfer buffer and program the DMA address.
+	 * Note that the NCR53C9x core can't handle EINPROGRESS so we set
+	 * BUS_DMA_NOWAIT.
+	 */
+	if (*dmasize != 0) {
+		error = bus_dmamap_load(sc->sc_buffer_dmat, sc->sc_dmamap,
+		    *sc->sc_dmaaddr, *dmasize, lsi64854_map_scsi, sc,
+		    BUS_DMA_NOWAIT);
+		if (error != 0)
+			return (error);
+	}
+
+	if (sc->sc_rev == DMAREV_ESC) {
+		/* DMA ESC chip bug work-around */
+		bcnt = *dmasize;
+		if (((bcnt + (long)*sc->sc_dmaaddr) & PAGE_MASK_8K) != 0)
+			bcnt = roundup(bcnt, PAGE_SIZE_8K);
+		bus_write_4(sc->sc_res, L64854_REG_CNT, bcnt);
+	}
+
+	/* Setup the DMA control register. */
+	csr = L64854_GCSR(sc);
+
+	if (datain != 0)
+		csr |= L64854_WRITE;
+	else
+		csr &= ~L64854_WRITE;
+	csr |= L64854_INT_EN;
+
+	if (sc->sc_rev == DMAREV_HME)
+		csr |= (D_DSBL_SCSI_DRN | D_EN_DMA);
+
+	L64854_SCSR(sc, csr);
+
+	return (0);
+}
+
+/*
+ * Pseudo (chained) interrupt from the esp driver to kick the
+ * current running DMA transfer.  Called from ncr53c9x_intr()
+ * for now.
+ *
+ * return 1 if it was a DMA continue.
+ */
+static int
+lsi64854_scsi_intr(void *arg)
+{
+	struct lsi64854_softc *sc = arg;
+	struct ncr53c9x_softc *nsc = sc->sc_client;
+	bus_dma_tag_t dmat;
+	bus_dmamap_t dmam;
+	size_t dmasize;
+	int lxfer, resid, trans;
+	uint32_t csr;
+
+	csr = L64854_GCSR(sc);
+
+	DPRINTF(LDB_SCSI, ("%s: addr 0x%x, csr %b\n", __func__,
+	    bus_read_4(sc->sc_res, L64854_REG_ADDR), csr, DDMACSR_BITS));
+
+	if (csr & (D_ERR_PEND | D_SLAVE_ERR)) {
+		device_printf(sc->sc_dev, "error: csr=%b\n", csr,
+		    DDMACSR_BITS);
+		csr &= ~D_EN_DMA;	/* Stop DMA. */
+		/* Invalidate the queue; SLAVE_ERR bit is write-to-clear */
+		csr |= D_INVALIDATE | D_SLAVE_ERR;
+		L64854_SCSR(sc, csr);
+		return (-1);
+	}
+
+	/* This is an "assertion" :) */
+	if (sc->sc_active == 0)
+		panic("%s: DMA wasn't active", __func__);
+
+	DMA_DRAIN(sc, 0);
+
+	/* DMA has stopped */
+	csr &= ~D_EN_DMA;
+	L64854_SCSR(sc, csr);
+	sc->sc_active = 0;
+
+	dmasize = sc->sc_dmasize;
+	if (dmasize == 0) {
+		/* A "Transfer Pad" operation completed. */
+		DPRINTF(LDB_SCSI, ("%s: discarded %d bytes (tcl=%d, "
+		    "tcm=%d)\n", __func__, NCR_READ_REG(nsc, NCR_TCL) |
+		    (NCR_READ_REG(nsc, NCR_TCM) << 8),
+		    NCR_READ_REG(nsc, NCR_TCL), NCR_READ_REG(nsc, NCR_TCM)));
+		return (0);
+	}
+
+	resid = 0;
+	/*
+	 * If a transfer onto the SCSI bus gets interrupted by the device
+	 * (e.g. for a SAVEPOINTER message), the data in the FIFO counts
+	 * as residual since the NCR53C9X counter registers get decremented
+	 * as bytes are clocked into the FIFO.
+	 */
+	if ((csr & D_WRITE) == 0 &&
+	    (resid = (NCR_READ_REG(nsc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
+		DPRINTF(LDB_SCSI, ("%s: empty esp FIFO of %d ", __func__,
+		    resid));
+		if (nsc->sc_rev == NCR_VARIANT_FAS366 &&
+		    (NCR_READ_REG(nsc, NCR_CFG3) & NCRFASCFG3_EWIDE))
+			resid <<= 1;
+	}
+
+	if ((nsc->sc_espstat & NCRSTAT_TC) == 0) {
+		lxfer = nsc->sc_features & NCR_F_LARGEXFER;
+		/*
+		 * "Terminal count" is off, so read the residue
+		 * out of the NCR53C9X counter registers.
+		 */
+		resid += (NCR_READ_REG(nsc, NCR_TCL) |
+		    (NCR_READ_REG(nsc, NCR_TCM) << 8) |
+		    (lxfer != 0 ? (NCR_READ_REG(nsc, NCR_TCH) << 16) : 0));
+
+		if (resid == 0 && dmasize == 65536 && lxfer == 0)
+			/* A transfer of 64k is encoded as TCL=TCM=0. */
+			resid = 65536;
+	}
+
+	trans = dmasize - resid;
+	if (trans < 0) {			/* transferred < 0? */
+#if 0
+		/*
+		 * This situation can happen in perfectly normal operation
+		 * if the ESP is reselected while using DMA to select
+		 * another target.  As such, don't print the warning.
+		 */
+		device_printf(sc->sc_dev, "xfer (%d) > req (%d)\n", trans,
+		    dmasize);
+#endif
+		trans = dmasize;
+	}
+
+	DPRINTF(LDB_SCSI, ("%s: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
+	    __func__, NCR_READ_REG(nsc, NCR_TCL), NCR_READ_REG(nsc, NCR_TCM),
+	    (nsc->sc_features & NCR_F_LARGEXFER) != 0 ?
+	    NCR_READ_REG(nsc, NCR_TCH) : 0, trans, resid));
+
+	if (dmasize != 0) {
+		dmat = sc->sc_buffer_dmat;
+		dmam = sc->sc_dmamap;
+		bus_dmamap_sync(dmat, dmam, (csr & D_WRITE) != 0 ?
+		    BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(dmat, dmam);
+	}
+
+	*sc->sc_dmalen -= trans;
+	*sc->sc_dmaaddr = (char *)*sc->sc_dmaaddr + trans;
+
+#if 0	/* this is not normal operation just yet */
+	if (*sc->sc_dmalen == 0 || nsc->sc_phase != nsc->sc_prevphase)
+		return (0);
+
+	/* and again */
+	dma_start(sc, sc->sc_dmaaddr, sc->sc_dmalen, DMACSR(sc) & D_WRITE);
+	return (1);
+#endif
+	return (0);
+}
+
+/*
+ * Pseudo (chained) interrupt to le(4) driver to handle DMA errors
+ */
+static int
+lsi64854_enet_intr(void *arg)
+{
+	struct lsi64854_softc *sc = arg;
+	uint32_t csr;
+	int i, rv;
+
+	csr = L64854_GCSR(sc);
+
+	/* If the DMA logic shows an interrupt, claim it */
+	rv = ((csr & E_INT_PEND) != 0) ? 1 : 0;
+
+	if (csr & (E_ERR_PEND | E_SLAVE_ERR)) {
+		device_printf(sc->sc_dev, "error: csr=%b\n", csr,
+		    EDMACSR_BITS);
+		csr &= ~L64854_EN_DMA;	/* Stop DMA. */
+		/* Invalidate the queue; SLAVE_ERR bit is write-to-clear */
+		csr |= E_INVALIDATE | E_SLAVE_ERR;
+		L64854_SCSR(sc, csr);
+		/* Will be drained with the LE_C0_IDON interrupt. */
+		sc->sc_dodrain = 1;
+		return (-1);
+	}
+
+	/* XXX - is this necessary with E_DSBL_WR_INVAL on? */
+	if (sc->sc_dodrain) {
+		i = 10;
+		csr |= E_DRAIN;
+		L64854_SCSR(sc, csr);
+		while (i-- > 0 && (L64854_GCSR(sc) & E_DRAINING))
+			DELAY(1);
+		sc->sc_dodrain = 0;
+	}
+
+	return (rv);
+}
+
+static void
+lsi64854_map_pp(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+	struct lsi64854_softc *sc;
+
+	sc = (struct lsi64854_softc *)arg;
+
+	if (error != 0)
+		return;
+	if (nsegs != 1)
+		panic("%s: cannot map %d segments\n", __func__, nsegs);
+
+	bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
+	    sc->sc_datain != 0 ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+	bus_write_4(sc->sc_res, L64854_REG_ADDR, segs[0].ds_addr);
+
+	bus_write_4(sc->sc_res, L64854_REG_CNT, sc->sc_dmasize);
+}
+
+/*
+ * Setup a DMA transfer.
+ */
+static int
+lsi64854_setup_pp(struct lsi64854_softc *sc, void **addr, size_t *len,
+    int datain, size_t *dmasize)
+{
+	int error;
+	uint32_t csr;
+
+	DMA_FLUSH(sc, 0);
+
+	sc->sc_dmaaddr = addr;
+	sc->sc_dmalen = len;
+	sc->sc_datain = datain;
+
+	DPRINTF(LDB_PP, ("%s: pp start %ld@%p,%d\n", __func__,
+	    (long)*sc->sc_dmalen, *sc->sc_dmaaddr, datain != 0 ? 1 : 0));
+
+	KASSERT(*dmasize <= sc->sc_maxdmasize,
+	    ("%s: transfer size %ld too large", __func__, (long)*dmasize));
+
+	sc->sc_dmasize = *dmasize;
+
+	DPRINTF(LDB_PP, ("%s: dmasize=%ld\n", __func__, (long)*dmasize));
+
+	/* Load the transfer buffer and program the DMA address. */
+	if (*dmasize != 0) {
+		error = bus_dmamap_load(sc->sc_buffer_dmat, sc->sc_dmamap,
+		    *sc->sc_dmaaddr, *dmasize, lsi64854_map_pp, sc,
+		    BUS_DMA_NOWAIT);
+		if (error != 0)
+			return (error);
+	}
+
+	/* Setup the DMA control register. */
+	csr = L64854_GCSR(sc);
+	csr &= ~L64854_BURST_SIZE;
+	if (sc->sc_burst == 32)
+		csr |= L64854_BURST_32;
+	else if (sc->sc_burst == 16)
+		csr |= L64854_BURST_16;
+	else
+		csr |= L64854_BURST_0;
+	csr |= P_EN_DMA | P_INT_EN | P_EN_CNT;
+#if 0
+	/* This bit is read-only in PP csr register. */
+	if (datain != 0)
+		csr |= P_WRITE;
+	else
+		csr &= ~P_WRITE;
+#endif
+	L64854_SCSR(sc, csr);
+
+	return (0);
+}
+
+/*
+ * Parallel port DMA interrupt
+ */
+static int
+lsi64854_pp_intr(void *arg)
+{
+	struct lsi64854_softc *sc = arg;
+	bus_dma_tag_t dmat;
+	bus_dmamap_t dmam;
+	size_t dmasize;
+	int ret, trans, resid = 0;
+	uint32_t csr;
+
+	csr = L64854_GCSR(sc);
+
+	DPRINTF(LDB_PP, ("%s: addr 0x%x, csr %b\n", __func__,
+	    bus_read_4(sc->sc_res, L64854_REG_ADDR), csr, PDMACSR_BITS));
+
+	if ((csr & (P_ERR_PEND | P_SLAVE_ERR)) != 0) {
+		resid = bus_read_4(sc->sc_res, L64854_REG_CNT);
+		device_printf(sc->sc_dev, "error: resid %d csr=%b\n", resid,
+		    csr, PDMACSR_BITS);
+		csr &= ~P_EN_DMA;	/* Stop DMA. */
+		/* Invalidate the queue; SLAVE_ERR bit is write-to-clear */
+		csr |= P_INVALIDATE | P_SLAVE_ERR;
+		L64854_SCSR(sc, csr);
+		return (-1);
+	}
+
+	ret = (csr & P_INT_PEND) != 0;
+
+	if (sc->sc_active != 0) {
+		DMA_DRAIN(sc, 0);
+		resid = bus_read_4(sc->sc_res, L64854_REG_CNT);
+	}
+
+	/* DMA has stopped */
+	csr &= ~D_EN_DMA;
+	L64854_SCSR(sc, csr);
+	sc->sc_active = 0;
+
+	dmasize = sc->sc_dmasize;
+	trans = dmasize - resid;
+	if (trans < 0)				/* transferred < 0? */
+		trans = dmasize;
+	*sc->sc_dmalen -= trans;
+	*sc->sc_dmaaddr = (char *)*sc->sc_dmaaddr + trans;
+
+	if (dmasize != 0) {
+		dmat = sc->sc_buffer_dmat;
+		dmam = sc->sc_dmamap;
+		bus_dmamap_sync(dmat, dmam, (csr & D_WRITE) != 0 ?
+		    BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(dmat, dmam);
+	}
+
+	return (ret != 0);
+}


Property changes on: trunk/sys/sparc64/sbus/lsi64854.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sbus/lsi64854reg.h
===================================================================
--- trunk/sys/sparc64/sbus/lsi64854reg.h	                        (rev 0)
+++ trunk/sys/sparc64/sbus/lsi64854reg.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,199 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: lsi64854reg.h,v 1.6 2008/04/28 20:23:50 martin Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/*	$FreeBSD: stable/10/sys/sparc64/sbus/lsi64854reg.h 219567 2011-03-12 14:33:32Z marius $ */
+
+/*
+ * LSI 64854 DMA engine. Contains three independent channels
+ * designed to interface with (a) a NCR539X SCSI controller,
+ * (b) a AM7990 Ethernet controller, (c) Parallel port hardware..
+ */
+
+/*
+ * Register offsets to bus handle.
+ */
+#define L64854_REG_CSR		0		/* Control bits */
+#define L64854_REG_ADDR		4		/* DMA Address */
+#define L64854_REG_CNT		8		/* DMA count */
+#define L64854_REG_CNT_MASK	0x00ffffff	/*   only 24 bits */
+#define L64854_REG_ENBAR	12		/* ENET Base register */
+#define L64854_REG_TEST		12		/* SCSI Test register */
+#define L64854_REG_HCR		16		/* PP Hardware Configuration */
+#define L64854_REG_OCR		18		/* PP Operation Configuration */
+#define L64854_REG_DR		20		/* PP Data register */
+#define L64854_REG_TCR		21		/* PP Transfer Control */
+#define L64854_REG_OR		22		/* PP Output register */
+#define L64854_REG_IR		23		/* PP Input register */
+#define L64854_REG_ICR		24		/* PP Interrupt Control */
+
+
+/*
+ * Control bits common to all three channels.
+ */
+#define L64854_INT_PEND	0x00000001	/* Interrupt pending */
+#define L64854_ERR_PEND	0x00000002	/* Error pending */
+#define L64854_DRAINING	0x0000000c	/* FIFO draining */
+#define L64854_INT_EN	0x00000010	/* Interrupt enable */
+#define L64854_INVALIDATE	0x00000020	/* Invalidate FIFO */
+#define L64854_SLAVE_ERR	0x00000040	/* Slave access size error */
+#define L64854_RESET	0x00000080	/* Reset device */
+#define L64854_WRITE	0x00000100	/* 1: xfer to memory */
+#define L64854_EN_DMA	0x00000200	/* enable DMA transfers */
+
+#define L64854_BURST_SIZE	0x000c0000	/* Read/write burst size */
+#define  L64854_BURST_0		0x00080000	/*   no bursts (SCSI-only) */
+#define  L64854_BURST_16	0x00000000	/*   16-byte bursts */
+#define  L64854_BURST_32    	0x00040000	/*   32-byte bursts */
+#define  L64854_BURST_64	0x000c0000	/*   64-byte bursts (fas) */
+
+#define L64854_RST_FAS366	0x08000000	/* FAS366 hardware reset */
+
+#define L64854_DEVID		0xf0000000	/* device ID bits */
+
+/*
+ * SCSI DMA control bits.
+ */
+#define D_INT_PEND	L64854_INT_PEND	/* interrupt pending */
+#define D_ERR_PEND	L64854_ERR_PEND	/* error pending */
+#define D_DRAINING	L64854_DRAINING	/* fifo draining */
+#define D_INT_EN	L64854_INT_EN	/* interrupt enable */
+#define D_INVALIDATE	L64854_INVALIDATE/* invalidate fifo */
+#define D_SLAVE_ERR	L64854_SLAVE_ERR/* slave access size error */
+#define D_RESET		L64854_RESET	/* reset scsi */
+#define D_WRITE		L64854_WRITE	/* 1 = dev -> mem */
+#define D_EN_DMA	L64854_EN_DMA	/* enable DMA requests */
+#define D_EN_CNT	0x00002000	/* enable byte counter */
+#define D_TC		0x00004000	/* terminal count */
+#define D_WIDE_EN	0x00008000	/* enable wide mode SBUS DMA (fas) */
+#define D_DSBL_CSR_DRN	0x00010000	/* disable fifo drain on csr */
+#define D_DSBL_SCSI_DRN	0x00020000	/* disable fifo drain on reg */
+
+#define D_DIAG		0x00100000	/* disable fifo drain on addr */
+#define D_TWO_CYCLE	0x00200000	/* 2 clocks per transfer */
+#define D_FASTER	0x00400000	/* 3 clocks per transfer */
+#define D_TCI_DIS	0x00800000	/* disable intr on D_TC */
+#define D_EN_NEXT	0x01000000	/* enable auto next address */
+#define D_DMA_ON	0x02000000	/* enable dma from scsi XXX */
+#define D_DSBL_PARITY_CHK \
+			0x02000000	/* disable checking for parity on bus (default 1:fas) */
+#define D_A_LOADED	0x04000000	/* address loaded */
+#define D_NA_LOADED	0x08000000	/* next address loaded */
+#define D_HW_RESET_FAS366 \
+			0x08000000	/* hardware reset FAS366 (fas) */
+#define D_DEV_ID	L64854_DEVID	/* device ID */
+#define  DMAREV_0	0x00000000	/* Sunray DMA */
+#define  DMAREV_ESC	0x40000000	/*  DMA ESC array */
+#define  DMAREV_1	0x80000000	/* 'DMA' */
+#define  DMAREV_PLUS	0x90000000	/* 'DMA+' */
+#define  DMAREV_2	0xa0000000	/* 'DMA2' */
+#define  DMAREV_HME     0xb0000000 	/* 'HME'  */
+
+/*
+ * revisions 0,1 and ESC have different bits.
+ */
+#define D_ESC_DRAIN	0x00000040	/* rev0,1,esc: drain fifo */
+#define D_ESC_R_PEND	0x00000400	/* rev0,1: request pending */
+#define D_ESC_BURST	0x00000800	/* DMA ESC: 16 byte bursts */
+#define D_ESC_AUTODRAIN	0x00040000	/* DMA ESC: Auto-drain */
+
+#define DDMACSR_BITS	"\177\020"				\
+	"b\00INT\0b\01ERR\0f\02\02DRAINING\0b\04IEN\0"		\
+	"b\06SLVERR\0b\07RST\0b\10WRITE\0b\11ENDMA\0"		\
+	"b\15ENCNT\0b\16TC\0\b\20DSBL_CSR_DRN\0"		\
+	"b\21DSBL_SCSI_DRN\0f\22\2BURST\0b\25TWOCYCLE\0"	\
+	"b\26FASTER\0b\27TCIDIS\0b\30ENNXT\0b\031DMAON\0"	\
+	"b\32ALOADED\0b\33NALOADED\0"
+
+
+/*
+ * ENET DMA control bits.
+ */
+#define E_INT_PEND	L64854_INT_PEND	/* interrupt pending */
+#define E_ERR_PEND	L64854_ERR_PEND	/* error pending */
+#define E_DRAINING	L64854_DRAINING	/* fifo draining */
+#define E_INT_EN	L64854_INT_EN	/* interrupt enable */
+#define E_INVALIDATE	L64854_INVALIDATE/* invalidate fifo */
+#define E_SLAVE_ERR	L64854_SLAVE_ERR/* slave access size error */
+#define E_RESET		L64854_RESET	/* reset ENET */
+#define E_reserved1	0x00000300	/* */
+#define E_DRAIN		0x00000400	/* force Ecache drain */
+#define E_DSBL_WR_DRN	0x00000800	/* disable Ecache drain on .. */
+#define E_DSBL_RD_DRN	0x00001000	/* disable Ecache drain on .. */
+#define E_reserved2	0x00006000	/* */
+#define E_ILACC		0x00008000	/* ... */
+#define E_DSBL_BUF_WR	0x00010000	/* no buffering of slave writes */
+#define E_DSBL_WR_INVAL	0x00020000	/* no Ecache invalidate on slave writes */
+
+#define E_reserved3	0x00100000	/* */
+#define E_LOOP_TEST	0x00200000	/* loopback mode */
+#define E_TP_AUI	0x00400000	/* 1 for TP, 0 for AUI */
+#define E_reserved4	0x0c800000	/* */
+#define E_DEV_ID	L64854_DEVID	/* ID bits */
+
+#define EDMACSR_BITS	"\177\020"				\
+	"b\00INT\0b\01ERR\0f\02\02DRAINING\0b\04IEN\0"		\
+	"b\06SLVERR\0b\07RST\0b\10WRITE\0b\12DRAIN\0"		\
+	"b\13DSBL_WR_DRN\0b\14DSBL_RD_DRN\0b\17ILACC\0"		\
+	"b\20DSBL_BUF_WR\0b\21DSBL_WR_INVAL\0"			\
+	"b\25LOOPTEST\0b\26TP\0"
+
+/*
+ * PP DMA control bits.
+ */
+#define P_INT_PEND	L64854_INT_PEND	/* interrupt pending */
+#define P_ERR_PEND	L64854_ERR_PEND	/* error pending */
+#define P_DRAINING	L64854_DRAINING	/* fifo draining */
+#define P_INT_EN	L64854_INT_EN	/* interrupt enable */
+#define P_INVALIDATE	L64854_INVALIDATE/* invalidate fifo */
+#define P_SLAVE_ERR	L64854_SLAVE_ERR/* slave access size error */
+#define P_RESET		L64854_RESET	/* reset PP */
+#define P_WRITE		L64854_WRITE	/* 1: xfer to memory */
+#define P_EN_DMA	L64854_EN_DMA	/* enable DMA transfers */
+#define P_reserved1	0x00001c00	/* */
+#define P_EN_CNT	0x00002000	/* enable counter */
+#define P_TC		0x00004000	/* terminal count */
+#define P_reserved2	0x00038000	/* */
+
+#define P_DIAG		0x00100000	/* ... */
+#define P_reserved3	0x00600000	/* */
+#define P_TCI_DIS	0x00800000	/* no interrupt on terminal count */
+#define P_EN_NEXT	0x01000000	/* enable DMA chaining */
+#define P_DMA_ON	0x02000000	/* DMA xfers enabled */
+#define P_A_LOADED	0x04000000	/* addr and byte count valid */
+#define P_NA_LOADED	0x08000000	/* next addr & count valid but not used */
+#define P_DEV_ID	L64854_DEVID	/* ID bits */
+
+#define PDMACSR_BITS	"\177\020"				\
+	"b\00INT\0b\01ERR\0f\02\02DRAINING\0b\04IEN\0"		\
+	"b\06SLVERR\0b\07RST\0b\10WRITE\0b\11ENDMA\0"		\
+	"b\15ENCNT\0b\16TC\0\b\24DIAG\0b\27TCIDIS\0"		\
+	"b\30ENNXT\0b\031DMAON\0b\32ALOADED\0b\33NALOADED\0"


Property changes on: trunk/sys/sparc64/sbus/lsi64854reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sbus/lsi64854var.h
===================================================================
--- trunk/sys/sparc64/sbus/lsi64854var.h	                        (rev 0)
+++ trunk/sys/sparc64/sbus/lsi64854var.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,95 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: lsi64854var.h,v 1.12 2008/04/28 20:23:50 martin Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/*	$FreeBSD: stable/10/sys/sparc64/sbus/lsi64854var.h 226947 2011-10-30 21:17:42Z marius $ */
+
+struct lsi64854_softc {
+	device_t		sc_dev;
+
+	struct resource		*sc_res;
+	u_int			sc_rev;		/* revision */
+	int			sc_burst;	/* max suported burst size */
+
+	int			sc_channel;
+#define L64854_CHANNEL_SCSI	1
+#define L64854_CHANNEL_ENET	2
+#define L64854_CHANNEL_PP	3
+	void			*sc_client;
+
+	int			sc_active;	/* DMA active? */
+	bus_dmamap_t		sc_dmamap;	/* DMA map for bus_dma_* */
+
+	bus_dma_tag_t		sc_parent_dmat;
+	bus_dma_tag_t		sc_buffer_dmat;
+	bus_size_t		sc_maxdmasize;
+	int			sc_datain;
+	size_t			sc_dmasize;
+	void			**sc_dmaaddr;
+	size_t			*sc_dmalen;
+
+	void	(*reset)(struct lsi64854_softc *);/* reset routine */
+	int	(*setup)(struct lsi64854_softc *, void **, size_t *,
+		    int, size_t *);		/* DMA setup */
+	int	(*intr)(void *);		/* interrupt handler */
+
+	u_int 			sc_dmactl;
+	int			sc_dodrain;
+};
+
+#define L64854_GCSR(sc)		bus_read_4((sc)->sc_res, L64854_REG_CSR)
+#define L64854_SCSR(sc, csr)	bus_write_4((sc)->sc_res, L64854_REG_CSR, csr)
+
+/*
+ * DMA engine interface functions.
+ */
+#define DMA_RESET(sc)			(((sc)->reset)(sc))
+#define DMA_INTR(sc)			(((sc)->intr)(sc))
+#define DMA_SETUP(sc, a, l, d, s)	(((sc)->setup)(sc, a, l, d, s))
+#define DMA_ISACTIVE(sc)		((sc)->sc_active)
+
+#define DMA_ENINTR(sc) do {			\
+	uint32_t csr = L64854_GCSR(sc);		\
+	csr |= L64854_INT_EN;			\
+	L64854_SCSR(sc, csr);			\
+} while (/* CONSTCOND */0)
+
+#define DMA_ISINTR(sc)	(L64854_GCSR(sc) & (D_INT_PEND|D_ERR_PEND))
+
+#define DMA_GO(sc) do {				\
+	uint32_t csr = L64854_GCSR(sc);		\
+	csr |= D_EN_DMA;			\
+	L64854_SCSR(sc, csr);			\
+	sc->sc_active = 1;			\
+} while (/* CONSTCOND */0)
+
+int	lsi64854_attach(struct lsi64854_softc *);
+int	lsi64854_detach(struct lsi64854_softc *);


Property changes on: trunk/sys/sparc64/sbus/lsi64854var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sbus/ofw_sbus.h
===================================================================
--- trunk/sys/sparc64/sbus/ofw_sbus.h	                        (rev 0)
+++ trunk/sys/sparc64/sbus/ofw_sbus.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,54 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ *
+ *	from: NetBSD: sbusvar.h,v 1.15 2008/04/28 20:23:36 martin Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/sbus/ofw_sbus.h 220939 2011-04-22 09:31:40Z marius $
+ */
+
+#ifndef _SPARC64_SBUS_OFW_SBUS_H_
+#define _SPARC64_SBUS_OFW_SBUS_H_
+
+/* Device register space description */
+struct sbus_regs {
+	u_int32_t	sbr_slot;
+	u_int32_t	sbr_offset;
+	u_int32_t	sbr_size;
+};
+
+/* Address translation across busses */
+struct sbus_ranges {
+	u_int32_t	cspace;		/* Client space */
+	u_int32_t	coffset;	/* Client offset */
+	u_int32_t	pspace;		/* Parent space */
+	u_int32_t	poffset;	/* Parent offset */
+	u_int32_t	size;		/* Size in bytes of this range */
+};
+
+#endif /* ! _SPARC64_SBUS_OFW_SBUS_H_ */


Property changes on: trunk/sys/sparc64/sbus/ofw_sbus.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sbus/sbus.c
===================================================================
--- trunk/sys/sparc64/sbus/sbus.c	                        (rev 0)
+++ trunk/sys/sparc64/sbus/sbus.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,939 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999-2002 Eduardo Horvath
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: sbus.c,v 1.50 2002/06/20 18:26:24 eeh Exp
+ */
+/*-
+ * Copyright (c) 2002 by Thomas Moestl <tmm at FreeBSD.org>.
+ * Copyright (c) 2005 Marius Strobl <marius at 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, this list of conditions and the following disclaimer.
+ *
+ * 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/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sbus/sbus.c 247621 2013-03-02 13:08:13Z marius $");
+
+/*
+ * SBus support.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/pcpu.h>
+#include <sys/queue.h>
+#include <sys/reboot.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/bus_common.h>
+#include <machine/bus_private.h>
+#include <machine/iommureg.h>
+#include <machine/iommuvar.h>
+#include <machine/resource.h>
+
+#include <sparc64/sbus/ofw_sbus.h>
+#include <sparc64/sbus/sbusreg.h>
+#include <sparc64/sbus/sbusvar.h>
+
+struct sbus_devinfo {
+	int			sdi_burstsz;
+	int			sdi_clockfreq;
+	int			sdi_slot;
+
+	struct ofw_bus_devinfo	sdi_obdinfo;
+	struct resource_list	sdi_rl;
+};
+
+/* Range descriptor, allocated for each sc_range. */
+struct sbus_rd {
+	bus_addr_t		rd_poffset;
+	bus_addr_t		rd_pend;
+	int			rd_slot;
+	bus_addr_t		rd_coffset;
+	bus_addr_t		rd_cend;
+	struct rman		rd_rman;
+	bus_space_handle_t	rd_bushandle;
+	struct resource		*rd_res;
+};
+
+struct sbus_softc {
+	device_t		sc_dev;
+	bus_dma_tag_t		sc_cdmatag;
+	int			sc_clockfreq;	/* clock frequency (in Hz) */
+	int			sc_nrange;
+	struct sbus_rd		*sc_rd;
+	int			sc_burst;	/* burst transfer sizes supp. */
+
+	struct resource		*sc_sysio_res;
+	int			sc_ign;		/* IGN for this sysio */
+	struct iommu_state	sc_is;		/* IOMMU state (iommuvar.h) */
+
+	struct resource		*sc_ot_ires;
+	void			*sc_ot_ihand;
+	struct resource		*sc_pf_ires;
+	void			*sc_pf_ihand;
+};
+
+#define	SYSIO_READ8(sc, off)						\
+	bus_read_8((sc)->sc_sysio_res, (off))
+#define	SYSIO_WRITE8(sc, off, v)					\
+	bus_write_8((sc)->sc_sysio_res, (off), (v))
+
+static device_probe_t sbus_probe;
+static device_attach_t sbus_attach;
+static bus_print_child_t sbus_print_child;
+static bus_probe_nomatch_t sbus_probe_nomatch;
+static bus_read_ivar_t sbus_read_ivar;
+static bus_get_resource_list_t sbus_get_resource_list;
+static bus_setup_intr_t sbus_setup_intr;
+static bus_alloc_resource_t sbus_alloc_resource;
+static bus_activate_resource_t sbus_activate_resource;
+static bus_adjust_resource_t sbus_adjust_resource;
+static bus_release_resource_t sbus_release_resource;
+static bus_get_dma_tag_t sbus_get_dma_tag;
+static ofw_bus_get_devinfo_t sbus_get_devinfo;
+
+static int sbus_inlist(const char *, const char *const *);
+static struct sbus_devinfo * sbus_setup_dinfo(device_t, struct sbus_softc *,
+    phandle_t);
+static void sbus_destroy_dinfo(struct sbus_devinfo *);
+static void sbus_intr_enable(void *);
+static void sbus_intr_disable(void *);
+static void sbus_intr_assign(void *);
+static void sbus_intr_clear(void *);
+static int sbus_find_intrmap(struct sbus_softc *, u_int, bus_addr_t *,
+    bus_addr_t *);
+static driver_intr_t sbus_overtemp;
+static driver_intr_t sbus_pwrfail;
+static int sbus_print_res(struct sbus_devinfo *);
+
+static device_method_t sbus_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		sbus_probe),
+	DEVMETHOD(device_attach,	sbus_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	sbus_print_child),
+	DEVMETHOD(bus_probe_nomatch,	sbus_probe_nomatch),
+	DEVMETHOD(bus_read_ivar,	sbus_read_ivar),
+	DEVMETHOD(bus_alloc_resource,	sbus_alloc_resource),
+	DEVMETHOD(bus_activate_resource, sbus_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	sbus_adjust_resource),
+	DEVMETHOD(bus_release_resource,	sbus_release_resource),
+	DEVMETHOD(bus_setup_intr,	sbus_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	DEVMETHOD(bus_get_resource_list, sbus_get_resource_list),
+	DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
+	DEVMETHOD(bus_get_dma_tag,	sbus_get_dma_tag),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	sbus_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	DEVMETHOD_END
+};
+
+static driver_t sbus_driver = {
+	"sbus",
+	sbus_methods,
+	sizeof(struct sbus_softc),
+};
+
+static devclass_t sbus_devclass;
+
+EARLY_DRIVER_MODULE(sbus, nexus, sbus_driver, sbus_devclass, NULL, NULL,
+    BUS_PASS_BUS);
+MODULE_DEPEND(sbus, nexus, 1, 1, 1);
+MODULE_VERSION(sbus, 1);
+
+#define	OFW_SBUS_TYPE	"sbus"
+#define	OFW_SBUS_NAME	"sbus"
+
+static const struct intr_controller sbus_ic = {
+	sbus_intr_enable,
+	sbus_intr_disable,
+	sbus_intr_assign,
+	sbus_intr_clear
+};
+
+struct sbus_icarg {
+	struct sbus_softc	*sica_sc;
+	bus_addr_t		sica_map;
+	bus_addr_t		sica_clr;
+};
+
+static const char *const sbus_order_first[] = {
+	"auxio",
+	"dma",
+	NULL
+};
+
+static int
+sbus_inlist(const char *name, const char *const *list)
+{
+	int i;
+
+	if (name == NULL)
+		return (0);
+	for (i = 0; list[i] != NULL; i++) {
+		if (strcmp(name, list[i]) == 0)
+			return (1);
+	}
+	return (0);
+}
+
+static int
+sbus_probe(device_t dev)
+{
+	const char *t;
+
+	t = ofw_bus_get_type(dev);
+	if (((t == NULL || strcmp(t, OFW_SBUS_TYPE) != 0)) &&
+	    strcmp(ofw_bus_get_name(dev), OFW_SBUS_NAME) != 0)
+		return (ENXIO);
+	device_set_desc(dev, "U2S UPA-SBus bridge");
+	return (0);
+}
+
+static int
+sbus_attach(device_t dev)
+{
+	struct sbus_softc *sc;
+	struct sbus_devinfo *sdi;
+	struct sbus_icarg *sica;
+	struct sbus_ranges *range;
+	struct resource *res;
+	struct resource_list *rl;
+	device_t cdev;
+	bus_addr_t intrclr, intrmap, phys;
+	bus_size_t size;
+	u_long vec;
+	phandle_t child, node;
+	uint32_t prop;
+	int i, j;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+	node = ofw_bus_get_node(dev);
+
+	i = 0;
+	sc->sc_sysio_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i,
+	    RF_ACTIVE);
+	if (sc->sc_sysio_res == NULL)
+		panic("%s: cannot allocate device memory", __func__);
+
+	if (OF_getprop(node, "interrupts", &prop, sizeof(prop)) == -1)
+		panic("%s: cannot get IGN", __func__);
+	sc->sc_ign = INTIGN(prop);
+
+	/*
+	 * Record clock frequency for synchronous SCSI.
+	 * IS THIS THE CORRECT DEFAULT??
+	 */
+	if (OF_getprop(node, "clock-frequency", &prop, sizeof(prop)) == -1)
+		prop = 25000000;
+	sc->sc_clockfreq = prop;
+	prop /= 1000;
+	device_printf(dev, "clock %d.%03d MHz\n", prop / 1000, prop % 1000);
+
+	/*
+	 * Collect address translations from the OBP.
+	 */
+	if ((sc->sc_nrange = OF_getprop_alloc(node, "ranges",
+	    sizeof(*range), (void **)&range)) == -1) {
+		panic("%s: error getting ranges property", __func__);
+	}
+	sc->sc_rd = malloc(sizeof(*sc->sc_rd) * sc->sc_nrange, M_DEVBUF,
+	    M_NOWAIT | M_ZERO);
+	if (sc->sc_rd == NULL)
+		panic("%s: cannot allocate rmans", __func__);
+	/*
+	 * Preallocate all space that the SBus bridge decodes, so that nothing
+	 * else gets in the way; set up rmans etc.
+	 */
+	rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
+	for (i = 0; i < sc->sc_nrange; i++) {
+		phys = range[i].poffset | ((bus_addr_t)range[i].pspace << 32);
+		size = range[i].size;
+		sc->sc_rd[i].rd_slot = range[i].cspace;
+		sc->sc_rd[i].rd_coffset = range[i].coffset;
+		sc->sc_rd[i].rd_cend = sc->sc_rd[i].rd_coffset + size;
+		j = resource_list_add_next(rl, SYS_RES_MEMORY, phys,
+		    phys + size - 1, size);
+		if ((res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &j,
+		    RF_ACTIVE)) == NULL)
+			panic("%s: cannot allocate decoded range", __func__);
+		sc->sc_rd[i].rd_bushandle = rman_get_bushandle(res);
+		sc->sc_rd[i].rd_rman.rm_type = RMAN_ARRAY;
+		sc->sc_rd[i].rd_rman.rm_descr = "SBus Device Memory";
+		if (rman_init(&sc->sc_rd[i].rd_rman) != 0 ||
+		    rman_manage_region(&sc->sc_rd[i].rd_rman, 0, size) != 0)
+			panic("%s: failed to set up memory rman", __func__);
+		sc->sc_rd[i].rd_poffset = phys;
+		sc->sc_rd[i].rd_pend = phys + size;
+		sc->sc_rd[i].rd_res = res;
+	}
+	free(range, M_OFWPROP);
+
+	/*
+	 * Get the SBus burst transfer size if burst transfers are supported.
+	 */
+	if (OF_getprop(node, "up-burst-sizes", &sc->sc_burst,
+	    sizeof(sc->sc_burst)) == -1 || sc->sc_burst == 0)
+		sc->sc_burst =
+		    (SBUS_BURST64_DEF << SBUS_BURST64_SHIFT) | SBUS_BURST_DEF;
+
+	/* initalise the IOMMU */
+
+	/* punch in our copies */
+	sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(SBUS_IOMMU_BITS);
+	sc->sc_is.is_bustag = rman_get_bustag(sc->sc_sysio_res);
+	sc->sc_is.is_bushandle = rman_get_bushandle(sc->sc_sysio_res);
+	sc->sc_is.is_iommu = SBR_IOMMU;
+	sc->sc_is.is_dtag = SBR_IOMMU_TLB_TAG_DIAG;
+	sc->sc_is.is_ddram = SBR_IOMMU_TLB_DATA_DIAG;
+	sc->sc_is.is_dqueue = SBR_IOMMU_QUEUE_DIAG;
+	sc->sc_is.is_dva = SBR_IOMMU_SVADIAG;
+	sc->sc_is.is_dtcmp = 0;
+	sc->sc_is.is_sb[0] = SBR_STRBUF;
+	sc->sc_is.is_sb[1] = 0;
+
+	/*
+	 * Note: the SBus IOMMU ignores the high bits of an address, so a NULL
+	 * DMA pointer will be translated by the first page of the IOTSB.
+	 * To detect bugs we'll allocate and ignore the first entry.
+	 */
+	iommu_init(device_get_nameunit(dev), &sc->sc_is, 3, -1, 1);
+
+	/* Create the DMA tag. */
+	if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
+	    sc->sc_is.is_pmaxaddr, ~0, NULL, NULL, sc->sc_is.is_pmaxaddr,
+	    0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_cdmatag) != 0)
+		panic("%s: bus_dma_tag_create failed", __func__);
+	/* Customize the tag. */
+	sc->sc_cdmatag->dt_cookie = &sc->sc_is;
+	sc->sc_cdmatag->dt_mt = &iommu_dma_methods;
+
+	/*
+	 * Hunt through all the interrupt mapping regs and register our
+	 * interrupt controller for the corresponding interrupt vectors.
+	 * We do this early in order to be able to catch stray interrupts.
+	 */
+	for (i = 0; i <= SBUS_MAX_INO; i++) {
+		if (sbus_find_intrmap(sc, i, &intrmap, &intrclr) == 0)
+			continue;
+		sica = malloc(sizeof(*sica), M_DEVBUF, M_NOWAIT);
+		if (sica == NULL)
+			panic("%s: could not allocate interrupt controller "
+			    "argument", __func__);
+		sica->sica_sc = sc;
+		sica->sica_map = intrmap;
+		sica->sica_clr = intrclr;
+#ifdef SBUS_DEBUG
+		device_printf(dev,
+		    "intr map (INO %d, %s) %#lx: %#lx, clr: %#lx\n",
+		    i, (i & INTMAP_OBIO_MASK) == 0 ? "SBus slot" : "OBIO",
+		    (u_long)intrmap, (u_long)SYSIO_READ8(sc, intrmap),
+		    (u_long)intrclr);
+#endif
+		j = intr_controller_register(INTMAP_VEC(sc->sc_ign, i),
+		    &sbus_ic, sica);
+		if (j != 0)
+			device_printf(dev, "could not register interrupt "
+			    "controller for INO %d (%d)\n", i, j);
+	}
+
+	/* Enable the over-temperature and power-fail interrupts. */
+	i = 4;
+	sc->sc_ot_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i,
+	    RF_ACTIVE);
+	if (sc->sc_ot_ires == NULL ||
+	    INTIGN(vec = rman_get_start(sc->sc_ot_ires)) != sc->sc_ign ||
+	    INTVEC(SYSIO_READ8(sc, SBR_THERM_INT_MAP)) != vec ||
+	    intr_vectors[vec].iv_ic != &sbus_ic ||
+	    bus_setup_intr(dev, sc->sc_ot_ires, INTR_TYPE_MISC | INTR_BRIDGE,
+	    NULL, sbus_overtemp, sc, &sc->sc_ot_ihand) != 0)
+		panic("%s: failed to set up temperature interrupt", __func__);
+	i = 3;
+	sc->sc_pf_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i,
+	    RF_ACTIVE);
+	if (sc->sc_pf_ires == NULL ||
+	    INTIGN(vec = rman_get_start(sc->sc_pf_ires)) != sc->sc_ign ||
+	    INTVEC(SYSIO_READ8(sc, SBR_POWER_INT_MAP)) != vec ||
+	    intr_vectors[vec].iv_ic != &sbus_ic ||
+	    bus_setup_intr(dev, sc->sc_pf_ires, INTR_TYPE_MISC | INTR_BRIDGE,
+	    NULL, sbus_pwrfail, sc, &sc->sc_pf_ihand) != 0)
+		panic("%s: failed to set up power fail interrupt", __func__);
+
+	/* Initialize the counter-timer. */
+	sparc64_counter_init(device_get_nameunit(dev),
+	    rman_get_bustag(sc->sc_sysio_res),
+	    rman_get_bushandle(sc->sc_sysio_res), SBR_TC0);
+
+	/*
+	 * Loop through ROM children, fixing any relative addresses
+	 * and then configuring each device.
+	 */
+	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+		if ((sdi = sbus_setup_dinfo(dev, sc, child)) == NULL)
+			continue;
+		/*
+		 * For devices where there are variants that are actually
+		 * split into two SBus devices (as opposed to the first
+		 * half of the device being a SBus device and the second
+		 * half hanging off of the first one) like 'auxio' and
+		 * 'SUNW,fdtwo' or 'dma' and 'esp' probe the SBus device
+		 * which is a prerequisite to the driver attaching to the
+		 * second one with a lower order. Saves us from dealing
+		 * with different probe orders in the respective device
+		 * drivers which generally is more hackish.
+		 */
+		cdev = device_add_child_ordered(dev, (OF_child(child) == 0 &&
+		    sbus_inlist(sdi->sdi_obdinfo.obd_name, sbus_order_first)) ?
+		    SBUS_ORDER_FIRST : SBUS_ORDER_NORMAL, NULL, -1);
+		if (cdev == NULL) {
+			device_printf(dev,
+			    "<%s>: device_add_child_ordered failed\n",
+			    sdi->sdi_obdinfo.obd_name);
+			sbus_destroy_dinfo(sdi);
+			continue;
+		}
+		device_set_ivars(cdev, sdi);
+	}
+	return (bus_generic_attach(dev));
+}
+
+static struct sbus_devinfo *
+sbus_setup_dinfo(device_t dev, struct sbus_softc *sc, phandle_t node)
+{
+	struct sbus_devinfo *sdi;
+	struct sbus_regs *reg;
+	u_int32_t base, iv, *intr;
+	int i, nreg, nintr, slot, rslot;
+
+	sdi = malloc(sizeof(*sdi), M_DEVBUF, M_ZERO | M_WAITOK);
+	if (ofw_bus_gen_setup_devinfo(&sdi->sdi_obdinfo, node) != 0) {
+		free(sdi, M_DEVBUF);
+		return (NULL);
+	}
+	resource_list_init(&sdi->sdi_rl);
+	slot = -1;
+	nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
+	if (nreg == -1) {
+		if (sdi->sdi_obdinfo.obd_type == NULL ||
+		    strcmp(sdi->sdi_obdinfo.obd_type, "hierarchical") != 0) {
+			device_printf(dev, "<%s>: incomplete\n",
+			    sdi->sdi_obdinfo.obd_name);
+			goto fail;
+		}
+	} else {
+		for (i = 0; i < nreg; i++) {
+			base = reg[i].sbr_offset;
+			if (SBUS_ABS(base)) {
+				rslot = SBUS_ABS_TO_SLOT(base);
+				base = SBUS_ABS_TO_OFFSET(base);
+			} else
+				rslot = reg[i].sbr_slot;
+			if (slot != -1 && slot != rslot) {
+				device_printf(dev, "<%s>: multiple slots\n",
+				    sdi->sdi_obdinfo.obd_name);
+				free(reg, M_OFWPROP);
+				goto fail;
+			}
+			slot = rslot;
+
+			resource_list_add(&sdi->sdi_rl, SYS_RES_MEMORY, i,
+			    base, base + reg[i].sbr_size, reg[i].sbr_size);
+		}
+		free(reg, M_OFWPROP);
+	}
+	sdi->sdi_slot = slot;
+
+	/*
+	 * The `interrupts' property contains the SBus interrupt level.
+	 */
+	nintr = OF_getprop_alloc(node, "interrupts", sizeof(*intr),
+	    (void **)&intr);
+	if (nintr != -1) {
+		for (i = 0; i < nintr; i++) {
+			iv = intr[i];
+			/*
+			 * SBus card devices need the slot number encoded into
+			 * the vector as this is generally not done.
+			 */
+			if ((iv & INTMAP_OBIO_MASK) == 0)
+				iv |= slot << 3;
+			iv = INTMAP_VEC(sc->sc_ign, iv);
+			resource_list_add(&sdi->sdi_rl, SYS_RES_IRQ, i,
+			    iv, iv, 1);
+		}
+		free(intr, M_OFWPROP);
+	}
+	if (OF_getprop(node, "burst-sizes", &sdi->sdi_burstsz,
+	    sizeof(sdi->sdi_burstsz)) == -1)
+		sdi->sdi_burstsz = sc->sc_burst;
+	else
+		sdi->sdi_burstsz &= sc->sc_burst;
+	if (OF_getprop(node, "clock-frequency", &sdi->sdi_clockfreq,
+	    sizeof(sdi->sdi_clockfreq)) == -1)
+		sdi->sdi_clockfreq = sc->sc_clockfreq;
+
+	return (sdi);
+
+fail:
+	sbus_destroy_dinfo(sdi);
+	return (NULL);
+}
+
+static void
+sbus_destroy_dinfo(struct sbus_devinfo *dinfo)
+{
+
+	resource_list_free(&dinfo->sdi_rl);
+	ofw_bus_gen_destroy_devinfo(&dinfo->sdi_obdinfo);
+	free(dinfo, M_DEVBUF);
+}
+
+static int
+sbus_print_child(device_t dev, device_t child)
+{
+	int rv;
+
+	rv = bus_print_child_header(dev, child);
+	rv += sbus_print_res(device_get_ivars(child));
+	rv += bus_print_child_footer(dev, child);
+	return (rv);
+}
+
+static void
+sbus_probe_nomatch(device_t dev, device_t child)
+{
+	const char *type;
+
+	device_printf(dev, "<%s>", ofw_bus_get_name(child));
+	sbus_print_res(device_get_ivars(child));
+	type = ofw_bus_get_type(child);
+	printf(" type %s (no driver attached)\n",
+	    type != NULL ? type : "unknown");
+}
+
+static int
+sbus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+	struct sbus_softc *sc;
+	struct sbus_devinfo *dinfo;
+
+	sc = device_get_softc(dev);
+	if ((dinfo = device_get_ivars(child)) == NULL)
+		return (ENOENT);
+	switch (which) {
+	case SBUS_IVAR_BURSTSZ:
+		*result = dinfo->sdi_burstsz;
+		break;
+	case SBUS_IVAR_CLOCKFREQ:
+		*result = dinfo->sdi_clockfreq;
+		break;
+	case SBUS_IVAR_IGN:
+		*result = sc->sc_ign;
+		break;
+	case SBUS_IVAR_SLOT:
+		*result = dinfo->sdi_slot;
+		break;
+	default:
+		return (ENOENT);
+	}
+	return (0);
+}
+
+static struct resource_list *
+sbus_get_resource_list(device_t dev, device_t child)
+{
+	struct sbus_devinfo *sdi;
+
+	sdi = device_get_ivars(child);
+	return (&sdi->sdi_rl);
+}
+
+static void
+sbus_intr_enable(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct sbus_icarg *sica = iv->iv_icarg;
+
+	SYSIO_WRITE8(sica->sica_sc, sica->sica_map,
+	    INTMAP_ENABLE(iv->iv_vec, iv->iv_mid));
+}
+
+static void
+sbus_intr_disable(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct sbus_icarg *sica = iv->iv_icarg;
+
+	SYSIO_WRITE8(sica->sica_sc, sica->sica_map, iv->iv_vec);
+}
+
+static void
+sbus_intr_assign(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct sbus_icarg *sica = iv->iv_icarg;
+
+	SYSIO_WRITE8(sica->sica_sc, sica->sica_map, INTMAP_TID(
+	    SYSIO_READ8(sica->sica_sc, sica->sica_map), iv->iv_mid));
+}
+
+static void
+sbus_intr_clear(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct sbus_icarg *sica = iv->iv_icarg;
+
+	SYSIO_WRITE8(sica->sica_sc, sica->sica_clr, INTCLR_IDLE);
+}
+
+static int
+sbus_find_intrmap(struct sbus_softc *sc, u_int ino, bus_addr_t *intrmapptr,
+    bus_addr_t *intrclrptr)
+{
+	bus_addr_t intrclr, intrmap;
+	int i;
+
+	if (ino > SBUS_MAX_INO) {
+		device_printf(sc->sc_dev, "out of range INO %d requested\n",
+		    ino);
+		return (0);
+	}
+
+	if ((ino & INTMAP_OBIO_MASK) == 0) {
+		intrmap = SBR_SLOT0_INT_MAP + INTSLOT(ino) * 8;
+		intrclr = SBR_SLOT0_INT_CLR +
+		    (INTSLOT(ino) * 8 * 8) + (INTPRI(ino) * 8);
+	} else {
+		intrclr = 0;
+		for (i = 0, intrmap = SBR_SCSI_INT_MAP;
+		    intrmap <= SBR_RESERVED_INT_MAP; intrmap += 8, i++) {
+			if (INTVEC(SYSIO_READ8(sc, intrmap)) ==
+			    INTMAP_VEC(sc->sc_ign, ino)) {
+				intrclr = SBR_SCSI_INT_CLR + i * 8;
+				break;
+			}
+		}
+		if (intrclr == 0)
+			return (0);
+	}
+	if (intrmapptr != NULL)
+		*intrmapptr = intrmap;
+	if (intrclrptr != NULL)
+		*intrclrptr = intrclr;
+	return (1);
+}
+
+static int
+sbus_setup_intr(device_t dev, device_t child, struct resource *ires, int flags,
+    driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
+{
+	struct sbus_softc *sc;
+	u_long vec;
+
+	sc = device_get_softc(dev);
+	/*
+	 * Make sure the vector is fully specified and we registered
+	 * our interrupt controller for it.
+	 */
+	vec = rman_get_start(ires);
+	if (INTIGN(vec) != sc->sc_ign || intr_vectors[vec].iv_ic != &sbus_ic) {
+		device_printf(dev, "invalid interrupt vector 0x%lx\n", vec);
+		return (EINVAL);
+	}
+	return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr,
+	    arg, cookiep));
+}
+
+static struct resource *
+sbus_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct sbus_softc *sc;
+	struct rman *rm;
+	struct resource *rv;
+	struct resource_list *rl;
+	struct resource_list_entry *rle;
+	device_t schild;
+	bus_addr_t toffs;
+	bus_size_t tend;
+	int i, slot;
+	int isdefault, passthrough;
+
+	isdefault = (start == 0UL && end == ~0UL);
+	passthrough = (device_get_parent(child) != bus);
+	rle = NULL;
+	sc = device_get_softc(bus);
+	rl = BUS_GET_RESOURCE_LIST(bus, child);
+	switch (type) {
+	case SYS_RES_IRQ:
+		return (resource_list_alloc(rl, bus, child, type, rid, start,
+		    end, count, flags));
+	case SYS_RES_MEMORY:
+		if (!passthrough) {
+			rle = resource_list_find(rl, type, *rid);
+			if (rle == NULL)
+				return (NULL);
+			if (rle->res != NULL)
+				panic("%s: resource entry is busy", __func__);
+			if (isdefault) {
+				start = rle->start;
+				count = ulmax(count, rle->count);
+				end = ulmax(rle->end, start + count - 1);
+			}
+		}
+		rm = NULL;
+		schild = child;
+		while (device_get_parent(schild) != bus)
+			schild = device_get_parent(schild);
+		slot = sbus_get_slot(schild);
+		for (i = 0; i < sc->sc_nrange; i++) {
+			if (sc->sc_rd[i].rd_slot != slot ||
+			    start < sc->sc_rd[i].rd_coffset ||
+			    start > sc->sc_rd[i].rd_cend)
+				continue;
+			/* Disallow cross-range allocations. */
+			if (end > sc->sc_rd[i].rd_cend)
+				return (NULL);
+			/* We've found the connection to the parent bus */
+			toffs = start - sc->sc_rd[i].rd_coffset;
+			tend = end - sc->sc_rd[i].rd_coffset;
+			rm = &sc->sc_rd[i].rd_rman;
+			break;
+		}
+		if (rm == NULL)
+			return (NULL);
+
+		rv = rman_reserve_resource(rm, toffs, tend, count, flags &
+		    ~RF_ACTIVE, child);
+		if (rv == NULL)
+			return (NULL);
+		rman_set_rid(rv, *rid);
+
+		if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child,
+		    type, *rid, rv)) {
+			rman_release_resource(rv);
+			return (NULL);
+		}
+		if (!passthrough)
+			rle->res = rv;
+		return (rv);
+	default:
+		return (NULL);
+	}
+}
+
+static int
+sbus_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	struct sbus_softc *sc;
+	struct bus_space_tag *tag;
+	int i;
+
+	switch (type) {
+	case SYS_RES_IRQ:
+		return (bus_generic_activate_resource(bus, child, type, rid,
+		    r));
+	case SYS_RES_MEMORY:
+		sc = device_get_softc(bus);
+		for (i = 0; i < sc->sc_nrange; i++) {
+			if (rman_is_region_manager(r,
+			    &sc->sc_rd[i].rd_rman) != 0) {
+				tag = sparc64_alloc_bus_tag(r,
+				    rman_get_bustag(sc->sc_sysio_res),
+				    SBUS_BUS_SPACE, NULL);
+				if (tag == NULL)
+					return (ENOMEM);
+				rman_set_bustag(r, tag);
+				rman_set_bushandle(r,
+				    sc->sc_rd[i].rd_bushandle +
+				    rman_get_start(r));
+				return (rman_activate_resource(r));
+			}
+		}
+		/* FALLTHROUGH */
+	default:
+		return (EINVAL);
+	}
+}
+
+static int
+sbus_adjust_resource(device_t bus, device_t child, int type,
+    struct resource *r, u_long start, u_long end)
+{
+	struct sbus_softc *sc;
+	int i;
+
+	if (type == SYS_RES_MEMORY) {
+		sc = device_get_softc(bus);
+		for (i = 0; i < sc->sc_nrange; i++)
+			if (rman_is_region_manager(r,
+			    &sc->sc_rd[i].rd_rman) != 0)
+				return (rman_adjust_resource(r, start, end));
+		return (EINVAL);
+	}
+	return (bus_generic_adjust_resource(bus, child, type, r, start, end));
+}
+
+static int
+sbus_release_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	struct resource_list *rl;
+	struct resource_list_entry *rle;
+	int error, passthrough;
+
+	passthrough = (device_get_parent(child) != bus);
+	rl = BUS_GET_RESOURCE_LIST(bus, child);
+	if (type == SYS_RES_MEMORY) {
+		if ((rman_get_flags(r) & RF_ACTIVE) != 0) {
+			error = bus_deactivate_resource(child, type, rid, r);
+			if (error)
+				return (error);
+		}
+		error = rman_release_resource(r);
+		if (error != 0)
+			return (error);
+		if (!passthrough) {
+			rle = resource_list_find(rl, type, rid);
+			KASSERT(rle != NULL,
+			    ("%s: resource entry not found!", __func__));
+			KASSERT(rle->res != NULL,
+			   ("%s: resource entry is not busy", __func__));
+			rle->res = NULL;
+		}
+		return (0);
+	}
+	return (resource_list_release(rl, bus, child, type, rid, r));
+}
+
+static bus_dma_tag_t
+sbus_get_dma_tag(device_t bus, device_t child)
+{
+	struct sbus_softc *sc;
+
+	sc = device_get_softc(bus);
+	return (sc->sc_cdmatag);
+}
+
+static const struct ofw_bus_devinfo *
+sbus_get_devinfo(device_t bus, device_t child)
+{
+	struct sbus_devinfo *sdi;
+
+	sdi = device_get_ivars(child);
+	return (&sdi->sdi_obdinfo);
+}
+
+/*
+ * Handle an overtemp situation.
+ *
+ * SPARCs have temperature sensors which generate interrupts
+ * if the machine's temperature exceeds a certain threshold.
+ * This handles the interrupt and powers off the machine.
+ * The same needs to be done to PCI controller drivers.
+ */
+static void
+sbus_overtemp(void *arg __unused)
+{
+	static int shutdown;
+
+	/* As the interrupt is cleared we may be called multiple times. */
+	if (shutdown != 0)
+		return;
+	shutdown++;
+	printf("DANGER: OVER TEMPERATURE detected\nShutting down NOW.\n");
+	shutdown_nice(RB_POWEROFF);
+}
+
+/* Try to shut down in time in case of power failure. */
+static void
+sbus_pwrfail(void *arg __unused)
+{
+	static int shutdown;
+
+	/* As the interrupt is cleared we may be called multiple times. */
+	if (shutdown != 0)
+		return;
+	shutdown++;
+	printf("Power failure detected\nShutting down NOW.\n");
+	shutdown_nice(RB_POWEROFF);
+}
+
+static int
+sbus_print_res(struct sbus_devinfo *sdi)
+{
+	int rv;
+
+	rv = 0;
+	rv += resource_list_print_type(&sdi->sdi_rl, "mem", SYS_RES_MEMORY,
+	    "%#lx");
+	rv += resource_list_print_type(&sdi->sdi_rl, "irq", SYS_RES_IRQ,
+	    "%ld");
+	return (rv);
+}


Property changes on: trunk/sys/sparc64/sbus/sbus.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sbus/sbusreg.h
===================================================================
--- trunk/sys/sparc64/sbus/sbusreg.h	                        (rev 0)
+++ trunk/sys/sparc64/sbus/sbusreg.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,146 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1996-1999 Eduardo Horvath
+ *
+ * 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.
+ *
+ * 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.
+ *
+ *	from: NetBSD: sbusreg.h,v 1.7 1999/06/07 05:28:03 eeh Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/sbus/sbusreg.h 172066 2007-09-06 19:16:30Z marius $
+ */
+
+#ifndef _SPARC64_SBUS_SBUSREG_H_
+#define _SPARC64_SBUS_SBUSREG_H_
+
+/*
+ * Sbus device addresses are obtained from the FORTH PROMs.  They come
+ * in `absolute' and `relative' address flavors, so we have to handle both.
+ * Relative addresses do *not* include the slot number.
+ */
+#define	SBUS_BASE		0xf8000000
+#define	SBUS_ADDR(slot, off)	(SBUS_BASE + ((slot) << 25) + (off))
+#define	SBUS_ABS(a)		((unsigned)(a) >= SBUS_BASE)
+#define	SBUS_ABS_TO_SLOT(a)	(((a) - SBUS_BASE) >> 25)
+#define	SBUS_ABS_TO_OFFSET(a)	(((a) - SBUS_BASE) & 0x1ffffff)
+
+/*
+ * Sun4u S-bus definitions.  Here's where we deal w/the machine
+ * dependencies of sysio.
+ *
+ * SYSIO implements or is the interface to several things:
+ *
+ * o The SBUS interface itself
+ * o The IOMMU
+ * o The DVMA units
+ * o The interrupt controller
+ * o The counter/timers
+ *
+ * Since it has registers to control lots of different things
+ * as well as several on-board SBUS devices and external SBUS
+ * slots scattered throughout its address space, it's a pain.
+ *
+ * One good point, however, is that all registers are 64-bit.
+ */
+#define	SBR_UPA_PORTID		0x0000	/* UPA port ID register */
+#define	SBR_UPA_CONFIG		0x0008	/* UPA config register */
+#define	SBR_CS			0x0010	/* SYSIO control/status register */
+#define	SBR_ECCC		0x0020	/* ECC control register */
+#define	SBR_UE_AFS		0x0030	/* Uncorrectable Error AFSR */
+#define	SBR_UE_AFA		0x0038	/* Uncorrectable Error AFAR */
+#define	SBR_CE_AFS		0x0040	/* Correctable Error AFSR */
+#define	SBR_CE_AFA		0x0048	/* Correctable Error AFAR */
+#define	SBR_PM_CTL		0x0100	/* Performance monitor control reg */
+#define	SBR_PM_COUNT		0x0108	/* Performance monitor counter reg */
+#define	SBR_CTL			0x2000	/* SBUS Control Register */
+#define	SBR_AFS			0x2010	/* SBUS AFSR */
+#define	SBR_AFA			0x2018	/* SBUS AFAR */
+#define	SBR_CONFIG0		0x2020	/* SBUS Slot 0 config register */
+#define	SBR_CONFIG1		0x2028	/* SBUS Slot 1 config register */
+#define	SBR_CONFIG2		0x2030	/* SBUS Slot 2 config register */
+#define	SBR_CONFIG3		0x2038	/* SBUS Slot 3 config register */
+#define	SBR_CONFIG13		0x2040	/* Slot 13 config register <audio> */
+#define	SBR_CONFIG14		0x2048	/* Slot 14 config register <macio> */
+#define	SBR_CONFIG15		0x2050	/* Slot 15 config register <slavio> */
+#define	SBR_IOMMU		0x2400	/* IOMMU register block */
+#define	SBR_STRBUF		0x2800	/* stream buffer register block */
+#define	SBR_SLOT0_INT_MAP	0x2c00	/* SBUS slot 0 interrupt map reg */
+#define	SBR_SLOT1_INT_MAP	0x2c08	/* SBUS slot 1 interrupt map reg */
+#define	SBR_SLOT2_INT_MAP	0x2c10	/* SBUS slot 2 interrupt map reg */
+#define	SBR_SLOT3_INT_MAP	0x2c18	/* SBUS slot 3 interrupt map reg */
+#define	SBR_INTR_RETRY_TIM	0x2c20	/* interrupt retry timer reg */
+#define	SBR_SCSI_INT_MAP	0x3000	/* SCSI interrupt map reg */
+#define	SBR_ETHER_INT_MAP	0x3008	/* ethernet interrupt map reg */
+#define	SBR_BPP_INT_MAP		0x3010	/* parallel interrupt map reg */
+#define	SBR_AUDIO_INT_MAP	0x3018	/* audio interrupt map reg */
+#define	SBR_POWER_INT_MAP	0x3020	/* power fail interrupt map reg */
+#define	SBR_SKBDMS_INT_MAP	0x3028	/* serial/kbd/mouse interrupt map reg */
+#define	SBR_FD_INT_MAP		0x3030	/* floppy interrupt map reg */
+#define	SBR_THERM_INT_MAP	0x3038	/* thermal warn interrupt map reg */
+#define	SBR_KBD_INT_MAP		0x3040	/* kbd [unused] interrupt map reg */
+#define	SBR_MOUSE_INT_MAP	0x3048	/* mouse [unused] interrupt map reg */
+#define	SBR_SERIAL_INT_MAP	0x3050	/* second serial interrupt map reg */
+#define	SBR_TIMER0_INT_MAP	0x3060	/* timer 0 interrupt map reg */
+#define	SBR_TIMER1_INT_MAP	0x3068	/* timer 1 interrupt map reg */
+#define	SBR_UE_INT_MAP		0x3070	/* UE interrupt map reg */
+#define	SBR_CE_INT_MAP		0x3078	/* CE interrupt map reg */
+#define	SBR_ASYNC_INT_MAP	0x3080	/* SBUS error interrupt map reg */
+#define	SBR_PWRMGT_INT_MAP	0x3088	/* power mgmt wake interrupt map reg */
+#define	SBR_UPAGR_INT_MAP	0x3090	/* UPA graphics interrupt map reg */
+#define	SBR_RESERVED_INT_MAP	0x3098	/* reserved interrupt map reg */
+/*
+ * Note: clear interrupt 0 registers are not really used
+ */
+#define	SBR_SLOT0_INT_CLR	0x3400	/* SBUS slot 0 clear int regs 0..7 */
+#define	SBR_SLOT1_INT_CLR	0x3440	/* SBUS slot 1 clear int regs 0..7 */
+#define	SBR_SLOT2_INT_CLR	0x3480	/* SBUS slot 2 clear int regs 0..7 */
+#define	SBR_SLOT3_INT_CLR	0x34c0	/* SBUS slot 3 clear int regs 0..7 */
+#define	SBR_SCSI_INT_CLR	0x3800	/* SCSI clear int reg */
+#define	SBR_ETHER_INT_CLR	0x3808	/* ethernet clear int reg */
+#define	SBR_BPP_INT_CLR		0x3810	/* parallel clear int reg */
+#define	SBR_AUDIO_INT_CLR	0x3818	/* audio clear int reg */
+#define	SBR_POWER_INT_CLR	0x3820	/* power fail clear int reg */
+#define	SBR_SKBDMS_INT_CLR	0x3828	/* serial/kbd/mouse clear int reg */
+#define	SBR_FD_INT_CLR		0x3830	/* floppy clear int reg */
+#define	SBR_THERM_INT_CLR	0x3838	/* thermal warn clear int reg */
+#define	SBR_KBD_INT_CLR		0x3840	/* kbd [unused] clear int reg */
+#define	SBR_MOUSE_INT_CLR	0x3848	/* mouse [unused] clear int reg */
+#define	SBR_SERIAL_INT_CLR	0x3850	/* second serial clear int reg */
+#define	SBR_TIMER0_INT_CLR	0x3860	/* timer 0 clear int reg */
+#define	SBR_TIMER1_INT_CLR	0x3868	/* timer 1 clear int reg */
+#define	SBR_UE_INT_CLR		0x3870	/* UE clear int reg */
+#define	SBR_CE_INT_CLR		0x3878	/* CE clear int reg */
+#define	SBR_ASYNC_INT_CLR	0x3880	/* SBUS error clr interrupt reg */
+#define	SBR_PWRMGT_INT_CLR	0x3888	/* power mgmt wake clr interrupt reg */
+#define	SBR_TC0			0x3c00	/* timer/counter 0 */
+#define	SBR_TC1			0x3c10	/* timer/counter 1 */
+#define	SBR_IOMMU_SVADIAG	0x4400	/* SBUS virtual addr diag reg */
+#define	SBR_IOMMU_QUEUE_DIAG	0x4500	/* IOMMU LRU queue diag 0..15 */
+#define	SBR_IOMMU_TLB_TAG_DIAG	0x4580	/* TLB tag diag 0..15 */
+#define	SBR_IOMMU_TLB_DATA_DIAG	0x4600 	/* TLB data RAM diag 0..31 */
+#define	SBR_INT_DIAG		0x4800	/* SBUS int state diag reg */
+#define	SBR_OBIO_DIAG		0x4808	/* OBIO and misc int state diag reg */
+#define	SBR_STRBUF_DIAG		0x5000	/* Streaming buffer diag regs */
+
+/* INO defines */
+#define	SBUS_MAX_INO		0x3f
+
+/* Width of the physical addresses the IOMMU translates to */
+#define	SBUS_IOMMU_BITS	41
+
+#endif /* _SPARC64_SBUS_SBUSREG_H_ */


Property changes on: trunk/sys/sparc64/sbus/sbusreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sbus/sbusvar.h
===================================================================
--- trunk/sys/sparc64/sbus/sbusvar.h	                        (rev 0)
+++ trunk/sys/sparc64/sbus/sbusvar.h	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,124 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 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) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 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: @(#)sbusvar.h	8.1 (Berkeley) 6/11/93
+ *	from: NetBSD: sbusvar.h,v 1.15 2008/04/28 20:23:36 martin Exp
+ *
+ * $FreeBSD: stable/10/sys/sparc64/sbus/sbusvar.h 219567 2011-03-12 14:33:32Z marius $
+ */
+
+#ifndef _SPARC64_SBUS_SBUSVAR_H_
+#define	_SPARC64_SBUS_SBUSVAR_H_
+
+/*
+ * Macros for probe order
+ */
+#define	SBUS_ORDER_FIRST	10
+#define	SBUS_ORDER_NORMAL	20
+
+/*
+ * PROM-reported DMA burst sizes for the SBus
+ */
+#define	SBUS_BURST_1		(1 << 0)
+#define	SBUS_BURST_2		(1 << 1)
+#define	SBUS_BURST_4		(1 << 2)
+#define	SBUS_BURST_8		(1 << 3)
+#define	SBUS_BURST_16		(1 << 4)
+#define	SBUS_BURST_32		(1 << 5)
+#define	SBUS_BURST_64		(1 << 6)
+#define	SBUS_BURST_MASK		((1 << SBUS_BURST_SIZE) - 1)
+#define	SBUS_BURST_SIZE		16
+#define	SBUS_BURST64_MASK	(SBUS_BURST_MASK << SBUS_BURST64_SHIFT)
+#define	SBUS_BURST64_SHIFT	16
+
+/* Used if no burst sizes are specified for the bus. */
+#define	SBUS_BURST_DEF \
+	(SBUS_BURST_1 | SBUS_BURST_2 | SBUS_BURST_4 | SBUS_BURST_8 | 	\
+	SBUS_BURST_16 | SBUS_BURST_32 | SBUS_BURST_64)
+#define	SBUS_BURST64_DEF \
+	(SBUS_BURST_8 | SBUS_BURST_16 | SBUS_BURST_32 | SBUS_BURST_64)
+
+enum sbus_device_ivars {
+	SBUS_IVAR_BURSTSZ,
+	SBUS_IVAR_CLOCKFREQ,
+	SBUS_IVAR_IGN,
+	SBUS_IVAR_SLOT,
+};
+
+/*
+ * Simplified accessors for sbus devices
+ */
+#define	SBUS_ACCESSOR(var, ivar, type) \
+	__BUS_ACCESSOR(sbus, var, SBUS, ivar, type)
+
+SBUS_ACCESSOR(burstsz,		BURSTSZ,	int)
+SBUS_ACCESSOR(clockfreq,	CLOCKFREQ,	int)
+SBUS_ACCESSOR(ign,		IGN,		int)
+SBUS_ACCESSOR(slot,		SLOT,		int)
+
+#undef SBUS_ACCESSOR
+
+#endif /* _SPARC64_SBUS_SBUSVAR_H_ */


Property changes on: trunk/sys/sparc64/sbus/sbusvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/ata_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/ata_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/ata_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,52 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/ata_machdep.c 240518 2012-09-14 21:28:56Z eadler $");
+
+#include <sys/param.h>
+#include <geom/geom_disk.h>
+#include <machine/md_var.h>
+
+void
+sparc64_ata_disk_firmware_geom_adjust(struct disk *disk)
+{
+
+	/*
+	 * The VTOC8 disk label only uses 16-bit fields for cylinders, heads
+	 * and sectors so the geometry of large disks has to be adjusted.
+	 * If the disk is > 32GB at 16 heads and 63 sectors, adjust to 255
+	 * sectors (this matches what the OpenSolaris dad(7D) driver does).
+	 * If the disk is even > 128GB, additionally adjust the heads to
+	 * 255.  This allows disks up to the 2TB limit of the extended VTOC8.
+	 * XXX the OpenSolaris dad(7D) driver limits the mediasize to 128GB.
+	 */
+	if (disk->d_mediasize > (off_t)65535 * 16 * 63 * disk->d_sectorsize)
+		disk->d_fwsectors = 255;
+	if (disk->d_mediasize > (off_t)65535 * 16 * 255 * disk->d_sectorsize)
+		disk->d_fwheads = 255;
+}


Property changes on: trunk/sys/sparc64/sparc64/ata_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/autoconf.c
===================================================================
--- trunk/sys/sparc64/sparc64/autoconf.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/autoconf.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,89 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/autoconf.c 221869 2011-05-14 01:53:38Z attilio $");
+
+#include "opt_isa.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <sys/kernel.h>
+
+#ifdef DEV_ISA
+#include <isa/isavar.h>
+extern device_t isa_bus_device;
+#endif
+
+static device_t nexusdev;
+
+static void	configure_first(void *);
+static void	configure(void *);
+static void	configure_final(void *);
+
+SYSINIT(configure1, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure_first, NULL);
+/* SI_ORDER_SECOND is hookable */
+SYSINIT(configure2, SI_SUB_CONFIGURE, SI_ORDER_THIRD, configure, NULL);
+/* SI_ORDER_MIDDLE is hookable */
+SYSINIT(configure3, SI_SUB_CONFIGURE, SI_ORDER_ANY, configure_final, NULL);
+
+/*
+ * Determine i/o configuration for a machine.
+ */
+static void
+configure_first(void *dummy)
+{
+
+	nexusdev = device_add_child(root_bus, "nexus", 0);
+}
+
+static void
+configure(void *dummy)
+{
+
+	root_bus_configure();
+#ifdef DEV_ISA
+	/*
+	 * We bypass isa_probe_children(9) here in order to avoid
+	 * invasive probes done by identify-routines of ISA drivers,
+	 * which in turn can trigger master/target aborts, and the
+	 * addition of ISA hints, which might erroneously exist.
+	 */
+	if (isa_bus_device != NULL)
+		(void)bus_generic_attach(isa_bus_device);
+#endif
+}
+
+static void
+configure_final(void *dummy)
+{
+
+	cninit_finish();
+	cold = 0;
+}


Property changes on: trunk/sys/sparc64/sparc64/autoconf.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/bus_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/bus_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/bus_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,776 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1996, 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.
+ *
+ * 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) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 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.
+ */
+/*-
+ * Copyright (c) 1997, 1998 Justin T. Gibbs.
+ * All rights reserved.
+ * Copyright 2001 by Thomas Moestl <tmm at 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, this list of conditions, and the following disclaimer,
+ *    without modification, immediately at the beginning of the file.
+ * 2. 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.
+ *
+ *	from: @(#)machdep.c	8.6 (Berkeley) 1/14/94
+ *	from: NetBSD: machdep.c,v 1.221 2008/04/28 20:23:37 martin Exp
+ *	and
+ *	from: FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.24 2001/08/15
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/bus_machdep.c 294677 2016-01-24 19:21:53Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/rman.h>
+#include <sys/smp.h>
+#include <sys/systm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_param.h>
+#include <vm/vm_map.h>
+
+#include <machine/asi.h>
+#include <machine/atomic.h>
+#include <machine/bus.h>
+#include <machine/bus_private.h>
+#include <machine/cache.h>
+#include <machine/smp.h>
+#include <machine/tlb.h>
+
+static void nexus_bus_barrier(bus_space_tag_t, bus_space_handle_t,
+    bus_size_t, bus_size_t, int);
+
+/* ASIs for bus access */
+const int bus_type_asi[] = {
+	ASI_PHYS_BYPASS_EC_WITH_EBIT,		/* nexus */
+	ASI_PHYS_BYPASS_EC_WITH_EBIT,		/* SBus */
+	ASI_PHYS_BYPASS_EC_WITH_EBIT_L,		/* PCI configuration space */
+	ASI_PHYS_BYPASS_EC_WITH_EBIT_L,		/* PCI memory space */
+	ASI_PHYS_BYPASS_EC_WITH_EBIT_L,		/* PCI I/O space */
+	0
+};
+
+const int bus_stream_asi[] = {
+	ASI_PHYS_BYPASS_EC_WITH_EBIT,		/* nexus */
+	ASI_PHYS_BYPASS_EC_WITH_EBIT,		/* SBus */
+	ASI_PHYS_BYPASS_EC_WITH_EBIT,		/* PCI configuration space */
+	ASI_PHYS_BYPASS_EC_WITH_EBIT,		/* PCI memory space */
+	ASI_PHYS_BYPASS_EC_WITH_EBIT,		/* PCI I/O space */
+	0
+};
+
+/*
+ * Convenience function for manipulating driver locks from busdma (during
+ * busdma_swi, for example).  Drivers that don't provide their own locks
+ * should specify &Giant to dmat->lockfuncarg.  Drivers that use their own
+ * non-mutex locking scheme don't have to use this at all.
+ */
+void
+busdma_lock_mutex(void *arg, bus_dma_lock_op_t op)
+{
+	struct mtx *dmtx;
+
+	dmtx = (struct mtx *)arg;
+	switch (op) {
+	case BUS_DMA_LOCK:
+		mtx_lock(dmtx);
+		break;
+	case BUS_DMA_UNLOCK:
+		mtx_unlock(dmtx);
+		break;
+	default:
+		panic("Unknown operation 0x%x for busdma_lock_mutex!", op);
+	}
+}
+
+/*
+ * dflt_lock should never get called.  It gets put into the dma tag when
+ * lockfunc == NULL, which is only valid if the maps that are associated
+ * with the tag are meant to never be defered.
+ * XXX Should have a way to identify which driver is responsible here.
+ */
+static void
+dflt_lock(void *arg, bus_dma_lock_op_t op)
+{
+
+	panic("driver error: busdma dflt_lock called");
+}
+
+/*
+ * Allocate a device specific dma_tag.
+ */
+int
+bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
+    bus_addr_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr,
+    bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize,
+    int nsegments, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
+    void *lockfuncarg, bus_dma_tag_t *dmat)
+{
+	bus_dma_tag_t newtag;
+
+	/* Return a NULL tag on failure */
+	*dmat = NULL;
+
+	/* Enforce the usage of BUS_GET_DMA_TAG(). */
+	if (parent == NULL)
+		panic("%s: parent DMA tag NULL", __func__);
+
+	newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, M_NOWAIT);
+	if (newtag == NULL)
+		return (ENOMEM);
+
+	/*
+	 * The method table pointer and the cookie need to be taken over from
+	 * the parent.
+	 */
+	newtag->dt_cookie = parent->dt_cookie;
+	newtag->dt_mt = parent->dt_mt;
+
+	newtag->dt_parent = parent;
+	newtag->dt_alignment = alignment;
+	newtag->dt_boundary = boundary;
+	newtag->dt_lowaddr = trunc_page((vm_offset_t)lowaddr) + (PAGE_SIZE - 1);
+	newtag->dt_highaddr = trunc_page((vm_offset_t)highaddr) +
+	    (PAGE_SIZE - 1);
+	newtag->dt_filter = filter;
+	newtag->dt_filterarg = filterarg;
+	newtag->dt_maxsize = maxsize;
+	newtag->dt_nsegments = nsegments;
+	newtag->dt_maxsegsz = maxsegsz;
+	newtag->dt_flags = flags;
+	newtag->dt_ref_count = 1; /* Count ourselves */
+	newtag->dt_map_count = 0;
+
+	if (lockfunc != NULL) {
+		newtag->dt_lockfunc = lockfunc;
+		newtag->dt_lockfuncarg = lockfuncarg;
+	} else {
+		newtag->dt_lockfunc = dflt_lock;
+		newtag->dt_lockfuncarg = NULL;
+	}
+
+	newtag->dt_segments = NULL;
+
+	/* Take into account any restrictions imposed by our parent tag. */
+	newtag->dt_lowaddr = ulmin(parent->dt_lowaddr, newtag->dt_lowaddr);
+	newtag->dt_highaddr = ulmax(parent->dt_highaddr, newtag->dt_highaddr);
+	if (newtag->dt_boundary == 0)
+		newtag->dt_boundary = parent->dt_boundary;
+	else if (parent->dt_boundary != 0)
+		newtag->dt_boundary = ulmin(parent->dt_boundary,
+		    newtag->dt_boundary);
+	atomic_add_int(&parent->dt_ref_count, 1);
+
+	if (newtag->dt_boundary > 0)
+		newtag->dt_maxsegsz = ulmin(newtag->dt_maxsegsz,
+		    newtag->dt_boundary);
+
+	*dmat = newtag;
+	return (0);
+}
+
+int
+bus_dma_tag_destroy(bus_dma_tag_t dmat)
+{
+	bus_dma_tag_t parent;
+
+	if (dmat != NULL) {
+		if (dmat->dt_map_count != 0)
+			return (EBUSY);
+		while (dmat != NULL) {
+			parent = dmat->dt_parent;
+			atomic_subtract_int(&dmat->dt_ref_count, 1);
+			if (dmat->dt_ref_count == 0) {
+				if (dmat->dt_segments != NULL)
+					free(dmat->dt_segments, M_DEVBUF);
+				free(dmat, M_DEVBUF);
+				/*
+				 * Last reference count, so
+				 * release our reference
+				 * count on our parent.
+				 */
+				dmat = parent;
+			} else
+				dmat = NULL;
+		}
+	}
+	return (0);
+}
+
+/* Allocate/free a tag, and do the necessary management work. */
+int
+sparc64_dma_alloc_map(bus_dma_tag_t dmat, bus_dmamap_t *mapp)
+{
+
+	if (dmat->dt_segments == NULL) {
+		dmat->dt_segments = (bus_dma_segment_t *)malloc(
+		    sizeof(bus_dma_segment_t) * dmat->dt_nsegments, M_DEVBUF,
+		    M_NOWAIT);
+		if (dmat->dt_segments == NULL)
+			return (ENOMEM);
+	}
+	*mapp = malloc(sizeof(**mapp), M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (*mapp == NULL)
+		return (ENOMEM);
+
+	SLIST_INIT(&(*mapp)->dm_reslist);
+	dmat->dt_map_count++;
+	return (0);
+}
+
+void
+sparc64_dma_free_map(bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+
+	free(map, M_DEVBUF);
+	dmat->dt_map_count--;
+}
+
+static int
+nexus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
+{
+
+	return (sparc64_dma_alloc_map(dmat, mapp));
+}
+
+static int
+nexus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+
+	sparc64_dma_free_map(dmat, map);
+	return (0);
+}
+
+/*
+ * Add a single contiguous physical range to the segment list.
+ */
+static int
+nexus_dmamap_addseg(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t curaddr,
+    bus_size_t sgsize, bus_dma_segment_t *segs, int *segp)
+{
+	bus_addr_t baddr, bmask;
+	int seg;
+
+	/*
+	 * Make sure we don't cross any boundaries.
+	 */
+	bmask  = ~(dmat->dt_boundary - 1);
+	if (dmat->dt_boundary > 0) {
+		baddr = (curaddr + dmat->dt_boundary) & bmask;
+		if (sgsize > (baddr - curaddr))
+			sgsize = (baddr - curaddr);
+	}
+
+	/*
+	 * Insert chunk into a segment, coalescing with
+	 * previous segment if possible.
+	 */
+	seg = *segp;
+	if (seg == -1) {
+		seg = 0;
+		segs[seg].ds_addr = curaddr;
+		segs[seg].ds_len = sgsize;
+	} else {
+		if (curaddr == segs[seg].ds_addr + segs[seg].ds_len &&
+		    (segs[seg].ds_len + sgsize) <= dmat->dt_maxsegsz &&
+		    (dmat->dt_boundary == 0 ||
+		    (segs[seg].ds_addr & bmask) == (curaddr & bmask)))
+			segs[seg].ds_len += sgsize;
+		else {
+			if (++seg >= dmat->dt_nsegments)
+				return (0);
+			segs[seg].ds_addr = curaddr;
+			segs[seg].ds_len = sgsize;
+		}
+	}
+	*segp = seg;
+	return (sgsize);
+}
+
+/*
+ * Utility function to load a physical buffer.  segp contains
+ * the starting segment on entrace, and the ending segment on exit.
+ */
+static int
+nexus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf,
+    bus_size_t buflen, int flags, bus_dma_segment_t *segs, int *segp)
+{
+	bus_addr_t curaddr;
+	bus_size_t sgsize;
+
+	if (segs == NULL)
+		segs = dmat->dt_segments;
+
+	curaddr = buf;
+	while (buflen > 0) {
+		sgsize = MIN(buflen, dmat->dt_maxsegsz);
+		sgsize = nexus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
+		    segp);
+		if (sgsize == 0)
+			break;
+		curaddr += sgsize;
+		buflen -= sgsize;
+	}
+
+	/*
+	 * Did we fit?
+	 */
+	return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
+}
+
+/*
+ * Utility function to load a linear buffer.  segp contains
+ * the starting segment on entrace, and the ending segment on exit.
+ */
+static int
+nexus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
+    bus_size_t buflen, pmap_t pmap, int flags, bus_dma_segment_t *segs,
+    int *segp)
+{
+	bus_size_t sgsize;
+	bus_addr_t curaddr;
+	vm_offset_t vaddr = (vm_offset_t)buf;
+
+	if (segs == NULL)
+		segs = dmat->dt_segments;
+
+	while (buflen > 0) {
+		/*
+		 * Get the physical address for this segment.
+		 */
+		if (pmap == kernel_pmap)
+			curaddr = pmap_kextract(vaddr);
+		else
+			curaddr = pmap_extract(pmap, vaddr);
+
+		/*
+		 * Compute the segment size, and adjust counts.
+		 */
+		sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
+		if (sgsize > dmat->dt_maxsegsz)
+			sgsize = dmat->dt_maxsegsz;
+		if (buflen < sgsize)
+			sgsize = buflen;
+
+		sgsize = nexus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
+		    segp);
+		if (sgsize == 0)
+			break;
+
+		vaddr += sgsize;
+		buflen -= sgsize;
+	}
+
+	/*
+	 * Did we fit?
+	 */
+	return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
+}
+
+static void
+nexus_dmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map,
+    struct memdesc *mem, bus_dmamap_callback_t *callback, void *callback_arg)
+{
+
+}
+
+static bus_dma_segment_t *
+nexus_dmamap_complete(bus_dma_tag_t dmat, bus_dmamap_t map,
+    bus_dma_segment_t *segs, int nsegs, int error)
+{
+
+	if (segs == NULL)
+		segs = dmat->dt_segments;
+	return (segs);
+}
+
+/*
+ * Common function for unloading a DMA map.  May be called by
+ * bus-specific DMA map unload functions.
+ */
+static void
+nexus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+
+	map->dm_flags &= ~DMF_LOADED;
+}
+
+/*
+ * Common function for DMA map synchronization.  May be called
+ * by bus-specific DMA map synchronization functions.
+ */
+static void
+nexus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
+{
+
+	/*
+	 * We sync out our caches, but the bus must do the same.
+	 *
+	 * Actually a #Sync is expensive.  We should optimize.
+	 */
+	if ((op & BUS_DMASYNC_PREREAD) || (op & BUS_DMASYNC_PREWRITE)) {
+		/*
+		 * Don't really need to do anything, but flush any pending
+		 * writes anyway.
+		 */
+		membar(Sync);
+	}
+	if (op & BUS_DMASYNC_POSTWRITE) {
+		/* Nothing to do.  Handled by the bus controller. */
+	}
+}
+
+/*
+ * Common function for DMA-safe memory allocation.  May be called
+ * by bus-specific DMA memory allocation functions.
+ */
+static int
+nexus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags,
+    bus_dmamap_t *mapp)
+{
+	int mflags;
+
+	if (flags & BUS_DMA_NOWAIT)
+		mflags = M_NOWAIT;
+	else
+		mflags = M_WAITOK;
+	if (flags & BUS_DMA_ZERO)
+		mflags |= M_ZERO;
+
+	/*
+	 * XXX:
+	 * (dmat->dt_alignment <= dmat->dt_maxsize) is just a quick hack; the
+	 * exact alignment guarantees of malloc need to be nailed down, and
+	 * the code below should be rewritten to take that into account.
+	 *
+	 * In the meantime, we'll warn the user if malloc gets it wrong.
+	 */
+	if (dmat->dt_maxsize <= PAGE_SIZE &&
+	    dmat->dt_alignment <= dmat->dt_maxsize)
+		*vaddr = malloc(dmat->dt_maxsize, M_DEVBUF, mflags);
+	else {
+		/*
+		 * XXX use contigmalloc until it is merged into this
+		 * facility and handles multi-seg allocations.  Nobody
+		 * is doing multi-seg allocations yet though.
+		 */
+		*vaddr = contigmalloc(dmat->dt_maxsize, M_DEVBUF, mflags,
+		    0ul, dmat->dt_lowaddr,
+		    dmat->dt_alignment ? dmat->dt_alignment : 1UL,
+		    dmat->dt_boundary);
+	}
+	if (*vaddr == NULL)
+		return (ENOMEM);
+	if (vtophys(*vaddr) % dmat->dt_alignment)
+		printf("%s: failed to align memory properly.\n", __func__);
+	return (0);
+}
+
+/*
+ * Common function for freeing DMA-safe memory.  May be called by
+ * bus-specific DMA memory free functions.
+ */
+static void
+nexus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
+{
+
+	if (dmat->dt_maxsize <= PAGE_SIZE &&
+	    dmat->dt_alignment < dmat->dt_maxsize)
+		free(vaddr, M_DEVBUF);
+	else
+		contigfree(vaddr, dmat->dt_maxsize, M_DEVBUF);
+}
+
+static struct bus_dma_methods nexus_dma_methods = {
+	nexus_dmamap_create,
+	nexus_dmamap_destroy,
+	nexus_dmamap_load_phys,
+	nexus_dmamap_load_buffer,
+	nexus_dmamap_waitok,
+	nexus_dmamap_complete,
+	nexus_dmamap_unload,
+	nexus_dmamap_sync,
+	nexus_dmamem_alloc,
+	nexus_dmamem_free,
+};
+
+struct bus_dma_tag nexus_dmatag = {
+	NULL,
+	NULL,
+	1,
+	0,
+	~0,
+	~0,
+	NULL,		/* XXX */
+	NULL,
+	~0,
+	~0,
+	~0,
+	0,
+	0,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	&nexus_dma_methods,
+};
+
+/*
+ * Helpers to map/unmap bus memory
+ */
+int
+bus_space_map(bus_space_tag_t tag, bus_addr_t address, bus_size_t size,
+    int flags, bus_space_handle_t *handlep)
+{
+
+	return (sparc64_bus_mem_map(tag, address, size, flags, 0, handlep));
+}
+
+int
+sparc64_bus_mem_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size,
+    int flags, vm_offset_t vaddr, bus_space_handle_t *hp)
+{
+	vm_offset_t sva;
+	vm_offset_t va;
+	vm_paddr_t pa;
+	vm_size_t vsz;
+	u_long pm_flags;
+
+	/*
+	 * Given that we use physical access for bus_space(9) there's no need
+	 * need to map anything in unless BUS_SPACE_MAP_LINEAR is requested.
+	 */
+	if ((flags & BUS_SPACE_MAP_LINEAR) == 0) {
+		*hp = addr;
+		return (0);
+	}
+
+	if (tag->bst_cookie == NULL) {
+		printf("%s: resource cookie not set\n", __func__);
+		return (EINVAL);
+	}
+
+	size = round_page(size);
+	if (size == 0) {
+		printf("%s: zero size\n", __func__);
+		return (EINVAL);
+	}
+
+	switch (tag->bst_type) {
+	case PCI_CONFIG_BUS_SPACE:
+	case PCI_IO_BUS_SPACE:
+	case PCI_MEMORY_BUS_SPACE:
+		pm_flags = TD_IE;
+		break;
+	default:
+		pm_flags = 0;
+		break;
+	}
+
+	if ((flags & BUS_SPACE_MAP_CACHEABLE) == 0)
+		pm_flags |= TD_E;
+
+	if (vaddr != 0L)
+		sva = trunc_page(vaddr);
+	else {
+		if ((sva = kva_alloc(size)) == 0)
+			panic("%s: cannot allocate virtual memory", __func__);
+	}
+
+	pa = trunc_page(addr);
+	if ((flags & BUS_SPACE_MAP_READONLY) == 0)
+		pm_flags |= TD_W;
+
+	va = sva;
+	vsz = size;
+	do {
+		pmap_kenter_flags(va, pa, pm_flags);
+		va += PAGE_SIZE;
+		pa += PAGE_SIZE;
+	} while ((vsz -= PAGE_SIZE) > 0);
+	tlb_range_demap(kernel_pmap, sva, sva + size - 1);
+
+	/* Note: we preserve the page offset. */
+	rman_set_virtual(tag->bst_cookie, (void *)(sva | (addr & PAGE_MASK)));
+	return (0);
+}
+
+void
+bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t handle,
+    bus_size_t size)
+{
+
+	sparc64_bus_mem_unmap(tag, handle, size);
+}
+
+int
+sparc64_bus_mem_unmap(bus_space_tag_t tag, bus_space_handle_t handle,
+    bus_size_t size)
+{
+	vm_offset_t sva;
+	vm_offset_t va;
+	vm_offset_t endva;
+
+	if (tag->bst_cookie == NULL ||
+	    (sva = (vm_offset_t)rman_get_virtual(tag->bst_cookie)) == 0)
+		return (0);
+	sva = trunc_page(sva);
+	endva = sva + round_page(size);
+	for (va = sva; va < endva; va += PAGE_SIZE)
+		pmap_kremove_flags(va);
+	tlb_range_demap(kernel_pmap, sva, sva + size - 1);
+	kva_free(sva, size);
+	return (0);
+}
+
+/*
+ * Fake up a bus tag, for use by console drivers in early boot when the
+ * regular means to allocate resources are not yet available.
+ * Addr is the physical address of the desired start of the handle.
+ */
+bus_space_handle_t
+sparc64_fake_bustag(int space, bus_addr_t addr, struct bus_space_tag *ptag)
+{
+
+	ptag->bst_cookie = NULL;
+	ptag->bst_parent = NULL;
+	ptag->bst_type = space;
+	ptag->bst_bus_barrier = nexus_bus_barrier;
+	return (addr);
+}
+
+/*
+ * Allocate a bus tag.
+ */
+bus_space_tag_t
+sparc64_alloc_bus_tag(void *cookie, struct bus_space_tag *ptag, int type,
+    void *barrier)
+{
+	bus_space_tag_t bt;
+
+	bt = malloc(sizeof(struct bus_space_tag), M_DEVBUF, M_NOWAIT);
+	if (bt == NULL)
+		return (NULL);
+	bt->bst_cookie = cookie;
+	bt->bst_parent = ptag;
+	bt->bst_type = type;
+	bt->bst_bus_barrier = barrier;
+	return (bt);
+}
+
+/*
+ * Base bus space handlers.
+ */
+
+static void
+nexus_bus_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset,
+    bus_size_t size, int flags)
+{
+
+	/*
+	 * We have lots of alternatives depending on whether we're
+	 * synchronizing loads with loads, loads with stores, stores
+	 * with loads, or stores with stores.  The only ones that seem
+	 * generic are #Sync and #MemIssue.  I'll use #Sync for safety.
+	 */
+	switch(flags) {
+	case BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE:
+	case BUS_SPACE_BARRIER_READ:
+	case BUS_SPACE_BARRIER_WRITE:
+		membar(Sync);
+		break;
+	default:
+		panic("%s: unknown flags", __func__);
+	}
+	return;
+}
+
+struct bus_space_tag nexus_bustag = {
+	NULL,				/* cookie */
+	NULL,				/* parent bus tag */
+	NEXUS_BUS_SPACE,		/* type */
+	nexus_bus_barrier,		/* bus_space_barrier */
+};


Property changes on: trunk/sys/sparc64/sparc64/bus_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/cache.c
===================================================================
--- trunk/sys/sparc64/sparc64/cache.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/cache.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,189 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1996
+ *	The President and Fellows of Harvard College. All rights reserved.
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *	This product includes software developed by Harvard University.
+ *
+ * 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 Aaron Brown and
+ *	Harvard University.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*-
+ * Copyright (c) 2001 by Thomas Moestl <tmm at FreeBSD.org>.
+ * Copyright (c) 2008, 2010 Marius Strobl <marius at 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, 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 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: @(#)cache.c	8.2 (Berkeley) 10/30/93
+ *	from: NetBSD: cache.c,v 1.5 2000/12/06 01:47:50 mrg Exp
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/cache.c 230633 2012-01-27 23:21:54Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/pcpu.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <machine/cache.h>
+#include <machine/tlb.h>
+#include <machine/ver.h>
+
+cache_enable_t *cache_enable;
+cache_flush_t *cache_flush;
+dcache_page_inval_t *dcache_page_inval;
+icache_page_inval_t *icache_page_inval;
+
+u_int dcache_color_ignore;
+
+#define	OF_GET(h, n, v)	OF_getprop((h), (n), &(v), sizeof(v))
+
+static u_int cache_new_prop(u_int cpu_impl);
+
+static u_int
+cache_new_prop(u_int cpu_impl)
+{
+
+	switch (cpu_impl) {
+	case CPU_IMPL_ULTRASPARCIV:
+	case CPU_IMPL_ULTRASPARCIVp:
+		return (1);
+	default:
+		return (0);
+	}
+}
+
+/*
+ * Fill in the cache parameters using the CPU node.
+ */
+void
+cache_init(struct pcpu *pcpu)
+{
+	u_long set;
+	u_int use_new_prop;
+
+	/*
+	 * For CPUs which ignore TD_CV and support hardware unaliasing don't
+	 * bother doing page coloring.  This is equal across all CPUs.
+	 */
+	if (pcpu->pc_cpuid == 0 && pcpu->pc_impl == CPU_IMPL_SPARC64V)
+		dcache_color_ignore = 1;
+
+	use_new_prop = cache_new_prop(pcpu->pc_impl);
+	if (OF_GET(pcpu->pc_node, !use_new_prop ? "icache-size" :
+	    "l1-icache-size", pcpu->pc_cache.ic_size) == -1 ||
+	    OF_GET(pcpu->pc_node, !use_new_prop ? "icache-line-size" :
+	    "l1-icache-line-size", pcpu->pc_cache.ic_linesize) == -1 ||
+	    OF_GET(pcpu->pc_node, !use_new_prop ? "icache-associativity" :
+	    "l1-icache-associativity", pcpu->pc_cache.ic_assoc) == -1 ||
+	    OF_GET(pcpu->pc_node, !use_new_prop ? "dcache-size" :
+	    "l1-dcache-size", pcpu->pc_cache.dc_size) == -1 ||
+	    OF_GET(pcpu->pc_node, !use_new_prop ? "dcache-line-size" :
+	    "l1-dcache-line-size", pcpu->pc_cache.dc_linesize) == -1 ||
+	    OF_GET(pcpu->pc_node, !use_new_prop ? "dcache-associativity" :
+	    "l1-dcache-associativity", pcpu->pc_cache.dc_assoc) == -1 ||
+	    OF_GET(pcpu->pc_node, !use_new_prop ? "ecache-size" :
+	    "l2-cache-size", pcpu->pc_cache.ec_size) == -1 ||
+	    OF_GET(pcpu->pc_node, !use_new_prop ? "ecache-line-size" :
+	    "l2-cache-line-size", pcpu->pc_cache.ec_linesize) == -1 ||
+	    OF_GET(pcpu->pc_node, !use_new_prop ? "ecache-associativity" :
+	    "l2-cache-associativity", pcpu->pc_cache.ec_assoc) == -1)
+		OF_panic("%s: could not retrieve cache parameters", __func__);
+
+	set = pcpu->pc_cache.ic_size / pcpu->pc_cache.ic_assoc;
+	if ((set & ~(1UL << (ffs(set) - 1))) != 0)
+		OF_panic("%s: I$ set size not a power of 2", __func__);
+	if ((pcpu->pc_cache.dc_size &
+	    ~(1UL << (ffs(pcpu->pc_cache.dc_size) - 1))) != 0)
+		OF_panic("%s: D$ size not a power of 2", __func__);
+	/*
+	 * For CPUs which don't support unaliasing in hardware ensure that
+	 * the data cache doesn't have too many virtual colors.
+	 */
+	if (dcache_color_ignore == 0 && ((pcpu->pc_cache.dc_size /
+	    pcpu->pc_cache.dc_assoc) / PAGE_SIZE) != DCACHE_COLORS)
+		OF_panic("%s: too many D$ colors", __func__);
+	set = pcpu->pc_cache.ec_size / pcpu->pc_cache.ec_assoc;
+	if ((set & ~(1UL << (ffs(set) - 1))) != 0)
+		OF_panic("%s: E$ set size not a power of 2", __func__);
+
+	if (pcpu->pc_impl >= CPU_IMPL_ULTRASPARCIII) {
+		cache_enable = cheetah_cache_enable;
+		cache_flush = cheetah_cache_flush;
+		dcache_page_inval = cheetah_dcache_page_inval;
+		icache_page_inval = cheetah_icache_page_inval;
+		tlb_flush_nonlocked = cheetah_tlb_flush_nonlocked;
+		tlb_flush_user = cheetah_tlb_flush_user;
+	} else if (pcpu->pc_impl == CPU_IMPL_SPARC64V) {
+		cache_enable = zeus_cache_enable;
+		cache_flush = zeus_cache_flush;
+		dcache_page_inval = zeus_dcache_page_inval;
+		icache_page_inval = zeus_icache_page_inval;
+		tlb_flush_nonlocked = zeus_tlb_flush_nonlocked;
+		tlb_flush_user = zeus_tlb_flush_user;
+	} else if (pcpu->pc_impl >= CPU_IMPL_ULTRASPARCI &&
+	    pcpu->pc_impl < CPU_IMPL_ULTRASPARCIII) {
+		cache_enable = spitfire_cache_enable;
+		cache_flush = spitfire_cache_flush;
+		dcache_page_inval = spitfire_dcache_page_inval;
+		icache_page_inval = spitfire_icache_page_inval;
+		tlb_flush_nonlocked = spitfire_tlb_flush_nonlocked;
+		tlb_flush_user = spitfire_tlb_flush_user;
+	} else
+		OF_panic("%s: unknown CPU", __func__);
+}


Property changes on: trunk/sys/sparc64/sparc64/cache.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/cam_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/cam_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/cam_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,75 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/cam_machdep.c 228022 2011-11-27 15:43:40Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+
+#include <machine/md_var.h>
+
+int
+scsi_da_bios_params(struct ccb_calc_geometry *ccg)
+{
+	uint32_t secs_per_cylinder, size_mb;
+
+	/*
+	 * The VTOC8 disk label only uses 16-bit fields for cylinders, heads
+	 * and sectors so the geometry of large disks has to be adjusted.
+	 * We generally use the sizing used by cam_calc_geometry(9), except
+	 * when it would overflow the cylinders, in which case we use 255
+	 * heads and sectors.  This allows disks up to the 2TB limit of the
+	 * extended VTOC8.
+	 * XXX this doesn't match the sizing used by OpenSolaris, as that
+	 * would exceed the 8-bit ccg->heads and ccg->secs_per_track.
+	 */
+	if (ccg->block_size == 0)
+		return (0);
+	size_mb = (1024L * 1024L) / ccg->block_size;
+	if (size_mb == 0)
+		return (0);
+	size_mb = ccg->volume_size / size_mb;
+	if (ccg->volume_size > (uint64_t)65535 * 255 * 63) {
+		ccg->heads = 255;
+		ccg->secs_per_track = 255;
+	} else if (size_mb > 1024) {
+		ccg->heads = 255;
+		ccg->secs_per_track = 63;
+	} else {
+		ccg->heads = 64;
+		ccg->secs_per_track = 32;
+	}
+	secs_per_cylinder = ccg->heads * ccg->secs_per_track;
+	if (secs_per_cylinder == 0)
+		return (0);
+	ccg->cylinders = ccg->volume_size / secs_per_cylinder;
+	return (1);
+}


Property changes on: trunk/sys/sparc64/sparc64/cam_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/cheetah.c
===================================================================
--- trunk/sys/sparc64/sparc64/cheetah.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/cheetah.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,307 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Jake Burkholder.
+ * Copyright (c) 2005 - 2011 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/cheetah.c 223719 2011-07-02 11:14:54Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/asi.h>
+#include <machine/cache.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/dcr.h>
+#include <machine/lsu.h>
+#include <machine/smp.h>
+#include <machine/tlb.h>
+#include <machine/ver.h>
+#include <machine/vmparam.h>
+
+#define	CHEETAH_ICACHE_TAG_LOWER	0x30
+#define	CHEETAH_T16_ENTRIES		16
+#define	CHEETAH_DT512_ENTRIES		512
+#define	CHEETAH_IT128_ENTRIES		128
+#define	CHEETAH_IT512_ENTRIES		512
+
+/*
+ * CPU-specific initialization for Sun Cheetah and later CPUs
+ */
+void
+cheetah_init(u_int cpu_impl)
+{
+	u_long val;
+
+	/* Ensure the TSB Extension Registers hold 0 as TSB_Base. */
+
+	stxa(AA_DMMU_TSB_PEXT_REG, ASI_DMMU, 0);
+	stxa(AA_IMMU_TSB_PEXT_REG, ASI_IMMU, 0);
+	membar(Sync);
+
+	stxa(AA_DMMU_TSB_SEXT_REG, ASI_DMMU, 0);
+	/*
+	 * NB: the secondary context was removed from the iMMU.
+	 */
+	membar(Sync);
+
+	stxa(AA_DMMU_TSB_NEXT_REG, ASI_DMMU, 0);
+	stxa(AA_IMMU_TSB_NEXT_REG, ASI_IMMU, 0);
+	membar(Sync);
+
+	/*
+	 * Configure the first large dTLB to hold 4MB pages (e.g. for direct
+	 * mappings) for all three contexts and ensure the second one is set
+	 * up to hold 8k pages for them.  Note that this is constraint by
+	 * US-IV+, whose large dTLBs can only hold entries of certain page
+	 * sizes each.
+	 * For US-IV+, additionally ensure that the large iTLB is set up to
+	 * hold 8k pages for nucleus and primary context (still no secondary
+	 * iMMU context.
+	 * NB: according to documentation, changing the page size of the same
+	 * context requires a context demap before changing the corresponding
+	 * page size, but we hardly can flush our locked pages here, so we use
+	 * a demap all instead.
+	 */
+	stxa(TLB_DEMAP_ALL, ASI_DMMU_DEMAP, 0);
+	membar(Sync);
+	val = (TS_4M << TLB_PCXR_N_PGSZ0_SHIFT) |
+	    (TS_8K << TLB_PCXR_N_PGSZ1_SHIFT) |
+	    (TS_4M << TLB_PCXR_P_PGSZ0_SHIFT) |
+	    (TS_8K << TLB_PCXR_P_PGSZ1_SHIFT);
+	if (cpu_impl == CPU_IMPL_ULTRASPARCIVp)
+		val |= (TS_8K << TLB_PCXR_N_PGSZ_I_SHIFT) |
+		    (TS_8K << TLB_PCXR_P_PGSZ_I_SHIFT);
+	stxa(AA_DMMU_PCXR, ASI_DMMU, val);
+	val = (TS_4M << TLB_SCXR_S_PGSZ0_SHIFT) |
+	    (TS_8K << TLB_SCXR_S_PGSZ1_SHIFT);
+	stxa(AA_DMMU_SCXR, ASI_DMMU, val);
+	flush(KERNBASE);
+
+	/*
+	 * Ensure DCR_IFPOE is disabled as long as we haven't implemented
+	 * support for it (if ever) as most if not all firmware versions
+	 * apparently turn it on.  Not making use of DCR_IFPOE should also
+	 * avoid Cheetah erratum #109.
+	 */
+	val = rd(asr18) & ~DCR_IFPOE;
+	if (cpu_impl == CPU_IMPL_ULTRASPARCIVp) {
+		/*
+		 * Ensure the branch prediction mode is set to PC indexing
+		 * in order to work around US-IV+ erratum #2.
+		 */
+		val = (val & ~DCR_BPM_MASK) | DCR_BPM_PC;
+		/*
+		 * XXX disable dTLB parity error reporting as otherwise we
+		 * get seemingly false positives when copying in the user
+		 * window by simulating a fill trap on return to usermode in
+		 * case single issue is disabled, which thus appears to be
+		 * a CPU bug.
+		 */
+		val &= ~DCR_DTPE;
+	}
+	wr(asr18, val, 0);
+}
+
+/*
+ * Enable level 1 caches.
+ */
+void
+cheetah_cache_enable(u_int cpu_impl)
+{
+	u_long lsu;
+
+	lsu = ldxa(0, ASI_LSU_CTL_REG);
+	if (cpu_impl == CPU_IMPL_ULTRASPARCIII) {
+		/* Disable P$ due to US-III erratum #18. */
+		lsu &= ~LSU_PE;
+	}
+	stxa(0, ASI_LSU_CTL_REG, lsu | LSU_IC | LSU_DC);
+	flush(KERNBASE);
+}
+
+/*
+ * Flush all lines from the level 1 caches.
+ */
+void
+cheetah_cache_flush(void)
+{
+	u_long addr, lsu;
+	register_t s;
+
+	s = intr_disable();
+	for (addr = 0; addr < PCPU_GET(cache.dc_size);
+	    addr += PCPU_GET(cache.dc_linesize))
+		/*
+		 * Note that US-IV+ additionally require a membar #Sync before
+		 * a load or store to ASI_DCACHE_TAG.
+		 */
+		__asm __volatile(
+		    "membar #Sync;"
+		    "stxa %%g0, [%0] %1;"
+		    "membar #Sync"
+		    : : "r" (addr), "n" (ASI_DCACHE_TAG));
+
+	/* The I$ must be disabled when flushing it so ensure it's off. */
+	lsu = ldxa(0, ASI_LSU_CTL_REG);
+	stxa(0, ASI_LSU_CTL_REG, lsu & ~(LSU_IC));
+	flush(KERNBASE);
+	for (addr = CHEETAH_ICACHE_TAG_LOWER;
+	    addr < PCPU_GET(cache.ic_size) * 2;
+	    addr += PCPU_GET(cache.ic_linesize) * 2)
+		__asm __volatile(
+		    "stxa %%g0, [%0] %1;"
+		    "membar #Sync"
+		    : : "r" (addr), "n" (ASI_ICACHE_TAG));
+	stxa(0, ASI_LSU_CTL_REG, lsu);
+	flush(KERNBASE);
+	intr_restore(s);
+}
+
+/*
+ * Flush a physical page from the data cache.
+ */
+void
+cheetah_dcache_page_inval(vm_paddr_t spa)
+{
+	vm_paddr_t pa;
+	void *cookie;
+
+	KASSERT((spa & PAGE_MASK) == 0,
+	    ("%s: pa not page aligned", __func__));
+	cookie = ipi_dcache_page_inval(tl_ipi_cheetah_dcache_page_inval, spa);
+	for (pa = spa; pa < spa + PAGE_SIZE;
+	    pa += PCPU_GET(cache.dc_linesize))
+		stxa_sync(pa, ASI_DCACHE_INVALIDATE, 0);
+	ipi_wait(cookie);
+}
+
+/*
+ * Flush a physical page from the intsruction cache.  Instruction cache
+ * consistency is maintained by hardware.
+ */
+void
+cheetah_icache_page_inval(vm_paddr_t pa __unused)
+{
+
+}
+
+/*
+ * Flush all non-locked mappings from the TLBs.
+ */
+void
+cheetah_tlb_flush_nonlocked(void)
+{
+
+	stxa(TLB_DEMAP_ALL, ASI_DMMU_DEMAP, 0);
+	stxa(TLB_DEMAP_ALL, ASI_IMMU_DEMAP, 0);
+	flush(KERNBASE);
+}
+
+/*
+ * Flush all user mappings from the TLBs.
+ */
+void
+cheetah_tlb_flush_user(void)
+{
+	u_long data, tag;
+	register_t s;
+	u_int i, slot;
+
+	/*
+	 * We read ASI_{D,I}TLB_DATA_ACCESS_REG twice back-to-back in order
+	 * to work around errata of USIII and beyond.
+	 */
+	for (i = 0; i < CHEETAH_T16_ENTRIES; i++) {
+		slot = TLB_DAR_SLOT(TLB_DAR_T16, i);
+		s = intr_disable();
+		(void)ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+		data = ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+		intr_restore(s);
+		tag = ldxa(slot, ASI_DTLB_TAG_READ_REG);
+		if ((data & TD_V) != 0 && (data & TD_L) == 0 &&
+		    TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+			stxa_sync(slot, ASI_DTLB_DATA_ACCESS_REG, 0);
+		s = intr_disable();
+		(void)ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+		data = ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+		intr_restore(s);
+		tag = ldxa(slot, ASI_ITLB_TAG_READ_REG);
+		if ((data & TD_V) != 0 && (data & TD_L) == 0 &&
+		    TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+			stxa_sync(slot, ASI_ITLB_DATA_ACCESS_REG, 0);
+	}
+	for (i = 0; i < CHEETAH_DT512_ENTRIES; i++) {
+		slot = TLB_DAR_SLOT(TLB_DAR_DT512_0, i);
+		s = intr_disable();
+		(void)ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+		data = ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+		intr_restore(s);
+		tag = ldxa(slot, ASI_DTLB_TAG_READ_REG);
+		if ((data & TD_V) != 0 && TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+			stxa_sync(slot, ASI_DTLB_DATA_ACCESS_REG, 0);
+		slot = TLB_DAR_SLOT(TLB_DAR_DT512_1, i);
+		s = intr_disable();
+		(void)ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+		data = ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+		intr_restore(s);
+		tag = ldxa(slot, ASI_DTLB_TAG_READ_REG);
+		if ((data & TD_V) != 0 && TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+			stxa_sync(slot, ASI_DTLB_DATA_ACCESS_REG, 0);
+	}
+	if (PCPU_GET(impl) == CPU_IMPL_ULTRASPARCIVp) {
+		for (i = 0; i < CHEETAH_IT512_ENTRIES; i++) {
+			slot = TLB_DAR_SLOT(TLB_DAR_IT512, i);
+			s = intr_disable();
+			(void)ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+			data = ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+			intr_restore(s);
+			tag = ldxa(slot, ASI_ITLB_TAG_READ_REG);
+			if ((data & TD_V) != 0 &&
+			    TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+				stxa_sync(slot, ASI_ITLB_DATA_ACCESS_REG, 0);
+		}
+	} else {
+		for (i = 0; i < CHEETAH_IT128_ENTRIES; i++) {
+			slot = TLB_DAR_SLOT(TLB_DAR_IT128, i);
+			s = intr_disable();
+			(void)ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+			data = ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+			tag = ldxa(slot, ASI_ITLB_TAG_READ_REG);
+			intr_restore(s);
+			if ((data & TD_V) != 0 &&
+			    TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+				stxa_sync(slot, ASI_ITLB_DATA_ACCESS_REG, 0);
+		}
+	}
+}


Property changes on: trunk/sys/sparc64/sparc64/cheetah.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/clock.c
===================================================================
--- trunk/sys/sparc64/sparc64/clock.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/clock.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,60 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/clock.c 230633 2012-01-27 23:21:54Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
+
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+
+void
+DELAY(int usec)
+{
+	u_long end;
+
+	if (usec < 0)
+		return;
+
+	/*
+	 * We avoid being migrated to another CPU with a possibly
+	 * unsynchronized TICK timer while spinning.
+	 */
+	sched_pin();
+
+	end = rd(tick) + (u_long)usec * PCPU_GET(clock) / 1000000;
+	while (rd(tick) < end)
+		cpu_spinwait();
+
+	sched_unpin();
+}
+


Property changes on: trunk/sys/sparc64/sparc64/clock.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/counter.c
===================================================================
--- trunk/sys/sparc64/sparc64/counter.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/counter.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,111 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 by Thomas Moestl <tmm at 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, 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 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/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/counter.c 223961 2011-07-12 18:02:37Z marius $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+
+#include <machine/bus.h>
+#include <machine/bus_common.h>
+
+#define	COUNTER_MASK	((1 << 29) - 1)
+#define	COUNTER_FREQ	1000000
+#define	COUNTER_QUALITY	100
+
+/* Bits in the limit register. */
+#define	CTLR_INTEN	(1U << 31)	/* Enable timer interrupts */
+#define	CTLR_RELOAD	(1U << 30)	/* Zero counter on write to limit reg */
+#define	CTLR_PERIODIC	(1U << 29)	/* Wrap to 0 if limit is reached */
+
+/* Offsets of the registers for the two counters. */
+#define	CTR_CT0		0x00
+#define	CTR_CT1		0x10
+
+/* Register offsets from the base address. */
+#define	CTR_COUNT	0x00
+#define	CTR_LIMIT	0x08
+
+
+static timecounter_get_t counter_get_timecount;
+
+struct ct_softc {
+	bus_space_tag_t		sc_tag;
+	bus_space_handle_t	sc_handle;
+	bus_addr_t		sc_offset;
+};
+
+
+/*
+ * This is called from the psycho and sbus drivers.  It does not directly
+ * attach to the nexus because it shares register space with the bridge in
+ * question.
+ */
+void
+sparc64_counter_init(const char *name, bus_space_tag_t tag,
+    bus_space_handle_t handle, bus_addr_t offset)
+{
+	struct timecounter *tc;
+	struct ct_softc *sc;
+
+	printf("initializing counter-timer\n");
+	/*
+	 * Turn off interrupts from both counters.  Set the limit to the
+	 * maximum value (although that should not change anything with
+	 * CTLR_INTEN and CTLR_PERIODIC off).
+	 */
+	bus_space_write_8(tag, handle, offset + CTR_CT0 + CTR_LIMIT,
+	    COUNTER_MASK);
+	bus_space_write_8(tag, handle, offset + CTR_CT1 + CTR_LIMIT,
+	    COUNTER_MASK);
+	/* Register as a time counter. */
+	tc = malloc(sizeof(*tc), M_DEVBUF, M_WAITOK | M_ZERO);
+	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK);
+	sc->sc_tag = tag;
+	sc->sc_handle = handle;
+	sc->sc_offset = offset + CTR_CT0;
+	tc->tc_get_timecount = counter_get_timecount;
+	tc->tc_counter_mask = COUNTER_MASK;
+	tc->tc_frequency = COUNTER_FREQ;
+	tc->tc_name = strdup(name, M_DEVBUF);
+	tc->tc_priv = sc;
+	tc->tc_quality = COUNTER_QUALITY;
+	tc_init(tc);
+}
+
+static unsigned int
+counter_get_timecount(struct timecounter *tc)
+{
+	struct ct_softc *sc;
+
+	sc = tc->tc_priv;
+	return (bus_space_read_8(sc->sc_tag, sc->sc_handle, sc->sc_offset));
+}


Property changes on: trunk/sys/sparc64/sparc64/counter.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/db_disasm.c
===================================================================
--- trunk/sys/sparc64/sparc64/db_disasm.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/db_disasm.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,1032 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1994 David S. Miller, davem at nadzieja.rutgers.edu
+ * Copyright (c) 1995 Paul Kranenburg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by David Miller.
+ * 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.
+ *	from: NetBSD: db_disasm.c,v 1.9 2000/08/16 11:29:42 pk Exp
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/db_disasm.c 190003 2009-03-18 23:52:20Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <ddb/ddb.h>
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+
+#include <machine/db_machdep.h>
+#include <machine/instr.h>
+
+#define SIGN(v)			(((v)<0)?"-":"")
+
+/*
+ * All Sparc instructions are 32-bits, with the one exception being
+ * the set instruction which is actually a macro which expands into
+ * two instructions...
+ *
+ * There are 5 different fields that can be used to identify which
+ * operation is encoded into a particular 32-bit insn. There are 3
+ * formats for instuctions, which one being used is determined by
+ * bits 30-31 of the insn. Here are the bit fields and their names:
+ *
+ * 1100 0000 0000 0000 0000 0000 0000 0000 op field, determines format
+ * 0000 0001 1100 0000 0000 0000 0000 0000 op2 field, format 2 only
+ * 0000 0001 1111 1000 0000 0000 0000 0000 op3 field, format 3 only
+ * 0000 0000 0000 0000 0010 0000 0000 0000 f3i bit, format 3 only
+ * 0000 0000 0000 0000 0001 0000 0000 0000 X bit, format 3 only
+ */
+
+/* FORMAT macros used in sparc_i table to decode each opcode */
+#define FORMAT1(a)	(EIF_OP(a))
+#define FORMAT2(a,b)	(EIF_OP(a) | EIF_F2_OP2(b))
+/* For formats 3 and 4 */
+#define FORMAT3(a,b,c)	(EIF_OP(a) | EIF_F3_OP3(b) | EIF_F3_I(c))
+#define FORMAT3F(a,b,c)	(EIF_OP(a) | EIF_F3_OP3(b) | EIF_F3_OPF(c))
+
+/* Helper macros to construct OP3 & OPF */
+#define OP3_X(x,y)	((((x) & 3) << 4) | ((y) & 0xf))
+#define OPF_X(x,y)	((((x) & 0x1f) << 4) | ((y) & 0xf))
+
+/* COND condition codes field... */
+#define COND2(y,x)	(((((y)<<4) & 1)|((x) & 0xf)) << 14)
+
+struct sparc_insn {
+	  unsigned int match;
+	  const char* name;
+	  const char* format;
+};
+
+static const char *const regs[] = {
+	"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+	"o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
+	"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+	"i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7"
+};
+
+static const char *const priv_regs[] = {
+	"tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
+	"pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
+	"wstate", "fq",
+	"", "", "", "", "", "", "", "",
+	"", "", "", "", "", "", "", "ver"
+};
+
+static const char *const state_regs[] = {
+	"y", "", "ccr", "asi", "tick", "pc", "fprs", "asr",
+	"", "", "", "", "", "", "", "",
+	"pcr", "pic", "dcr", "gsr", "set_softint", "clr_softint", "softint",
+	"tick_cmpr", "sys_tick", "sys_tick_cmpr", "", "", "", "", "", "", ""
+};
+
+static const char *const ccodes[] = {
+	"fcc0", "fcc1", "fcc2", "fcc3", "icc", "", "xcc", ""
+};
+
+static const char *const prefetch[] = {
+	"n_reads", "one_read", "n_writes", "one_write", "page"
+};
+
+
+/* The sparc instruction table has a format field which tells what
+   the operand structure for this instruction is. Here are the codes:
+
+Modifiers (nust be first):
+	a -- opcode has annul bit
+	p -- opcode has branch prediction bit
+
+Codes:
+        1 -- source register operand stored in rs1
+	2 -- source register operand stored in rs2
+	d -- destination register operand stored in rd
+	3 -- floating source register in rs1
+	4 -- floating source register in rs2
+	e -- floating destination register in rd
+	i -- 13-bit immediate value stored in simm13
+	j -- 11-bit immediate value stored in simm11
+	l -- displacement using d16lo and d16hi
+	m -- 22-bit fcc displacement value
+	n -- 30-bit displacement used in call insns
+	o -- %fcc number specified in cc1 and cc0 fields
+	p -- address computed by the contents of rs1+rs2
+	q -- address computed by the contents of rs1+simm13
+	r -- prefetch
+	s -- %asi is implicit in the insn, rs1 value not used
+	t -- immediate 8-bit asi value
+	u -- 19-bit fcc displacement value
+	5 -- hard register, %fsr lower-half
+	6 -- hard register, %fsr all
+	7 -- [reg_addr rs1+rs2] imm_asi
+	8 -- [reg_addr rs1+simm13] %asi
+	9 -- logical or of the cmask and mmask fields (membar insn)
+	0 -- icc or xcc condition codes register
+	. -- %fcc, %icc, or %xcc in opf_cc field
+	r -- prefection function stored in fcn field
+	A -- privileged register encoded in rs1
+	B -- state register encoded in rs1
+	C -- %hi(value) where value is stored in imm22 field
+	D -- 32-bit shift count in shcnt32
+	E -- 64-bit shift count in shcnt64
+	F -- software trap number stored in sw_trap
+	G -- privileged register encoded in rd
+	H -- state register encoded in rd
+
+V8 only:
+	Y -- write y register
+	P -- write psr register
+	T -- write tbr register
+	W -- write wim register
+*/
+
+
+static const struct sparc_insn sparc_i[] = {
+
+	/*
+	 * Format 1: Call
+	 */
+	{(FORMAT1(1)), "call", "n"},
+
+	/*
+	 * Format 0: Sethi & Branches
+	 */
+	/* Illegal Instruction Trap */
+	{(FORMAT2(0, 0)), "illtrap", "m"},
+
+	/* Note: if imm22 is zero then this is actually a "nop" grrr... */
+	{(FORMAT2(0, 0x4)), "sethi", "Cd"},
+
+	/* Branch on Integer Co`ndition Codes "Bicc" */
+	{(FORMAT2(0, 2) | EIF_F2_COND(8)), "ba", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(0)), "bn", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(9)), "bne", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(1)), "be", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(10)), "bg", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(2)), "ble", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(11)), "bge", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(3)), "bl", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(12)), "bgu", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(4)), "bleu", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(13)), "bcc", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(5)), "bcs", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(14)), "bpos", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(6)), "bneg", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(15)), "bvc", "a,m"},
+	{(FORMAT2(0, 2) | EIF_F2_COND(7)), "bvs", "a,m"},
+
+	/* Branch on Integer Condition Codes with Prediction "BPcc" */
+	{(FORMAT2(0, 1) | EIF_F2_COND(8)), "ba", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(0)), "bn", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(9)), "bne", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(1)), "be", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(10)), "bg", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(2)), "ble", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(11)), "bge", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(3)), "bl", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(12)), "bgu", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(4)), "bleu", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(13)), "bcc", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(5)), "bcs", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(14)), "bpos", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(6)), "bneg", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(15)), "bvc", "ap,u"},
+	{(FORMAT2(0, 1) | EIF_F2_COND(7)), "bvs", "ap,u"},
+
+	/* Branch on Integer Register with Prediction "BPr" */
+	{(FORMAT2(0, 3) | EIF_F2_RCOND(1)), "brz", "ap,1l"},
+	{(FORMAT2(0, 3) | EIF_F2_A(1) | EIF_F2_P(1) |
+	    EIF_F2_RCOND(2)), "brlex", "ap,1l"},
+	{(FORMAT2(0, 3) | EIF_F2_RCOND(3)), "brlz", "ap,1l"},
+	{(FORMAT2(0, 3) | EIF_F2_RCOND(5)), "brnz", "ap,1l"},
+	{(FORMAT2(0, 3) | EIF_F2_RCOND(6)), "brgz", "ap,1l"},
+	{(FORMAT2(0, 3) | EIF_F2_RCOND(7)), "brgez", "ap,1l"},
+
+	/* Branch on Floating-Point Condition Codes with Prediction "FBPfcc" */
+	{(FORMAT2(0, 5) | EIF_F2_COND(8)), "fba", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(0)), "fbn", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(7)), "fbu", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(6)), "fbg", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(5)), "fbug", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(4)), "fbl", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(3)), "fbul", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(2)), "fblg", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(1)), "fbne", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(9)), "fbe", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(10)), "fbue", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(11)), "fbge", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(12)), "fbuge", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(13)), "fble", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(14)), "fbule", "ap,m"},
+	{(FORMAT2(0, 5) | EIF_F2_COND(15)), "fbo", "ap,m"},
+
+	/* Branch on Floating-Point Condition Codes "FBfcc" */
+	{(FORMAT2(0, 6) | EIF_F2_COND(8)), "fba", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(0)), "fbn", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(7)), "fbu", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(6)), "fbg", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(5)), "fbug", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(4)), "fbl", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(3)), "fbul", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(2)), "fblg", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(1)), "fbne", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(9)), "fbe", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(10)), "fbue", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(11)), "fbge", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(12)), "fbuge", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(13)), "fble", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(14)), "fbule", "a,m"},
+	{(FORMAT2(0, 6) | EIF_F2_COND(15)), "fbo", "a,m"},
+
+
+
+	/*
+	 * Format 3/2: Arithmetic & misc (table 32, appendix E)
+	 */
+	{FORMAT3(2, OP3_X(0,0), 0), "add", "12d"},
+	{FORMAT3(2, OP3_X(0,0), 1), "add", "1id"},
+	{FORMAT3(2, OP3_X(1,0), 0), "addcc", "12d"},
+	{FORMAT3(2, OP3_X(1,0), 1), "addcc", "1id"},
+	{FORMAT3(2, OP3_X(2,0), 0), "taddcc", "12d"},
+	{FORMAT3(2, OP3_X(2,0), 1), "taddcc", "1id"},
+	{(FORMAT3(2, 0x30, 1) | EIF_F3_RD(0xf)), "sir", "i"},
+	{FORMAT3(2, OP3_X(3,0), 0), "wr", "12H"},
+	{FORMAT3(2, OP3_X(3,0), 1), "wr", "1iH"},
+
+	{FORMAT3(2, OP3_X(0,1), 0), "and", "12d"},
+	{FORMAT3(2, OP3_X(0,1), 1), "and", "1id"},
+	{FORMAT3(2, OP3_X(1,1), 0), "andcc", "12d"},
+	{FORMAT3(2, OP3_X(1,1), 1), "andcc", "1id"},
+	{FORMAT3(2, OP3_X(2,1), 0), "tsubcc", "12d"},
+	{FORMAT3(2, OP3_X(2,1), 1), "tsubcc", "1id"},
+	{FORMAT3(2, OP3_X(3,1), 0), "saved", ""},
+	{FORMAT3(2, OP3_X(3,1), 0) | EIF_F3_FCN(1), "restored", ""},
+
+	{FORMAT3(2, OP3_X(0,2), 0), "or", "12d"},
+	{FORMAT3(2, OP3_X(0,2), 1), "or", "1id"},
+	{FORMAT3(2, OP3_X(1,2), 0), "orcc", "12d"},
+	{FORMAT3(2, OP3_X(1,2), 1), "orcc", "1id"},
+	{FORMAT3(2, OP3_X(2,2), 0), "taddcctv", "12d"},
+	{FORMAT3(2, OP3_X(2,2), 1), "taddcctv", "1id"},
+	{FORMAT3(2, OP3_X(3,2), 0), "wrpr", "12G"},
+	{FORMAT3(2, OP3_X(3,2), 1), "wrpr", "1iG"},
+
+	{FORMAT3(2, OP3_X(0,3), 0), "xor", "12d"},
+	{FORMAT3(2, OP3_X(0,3), 1), "xor", "1id"},
+	{FORMAT3(2, OP3_X(1,3), 0), "xorcc", "12d"},
+	{FORMAT3(2, OP3_X(1,3), 1), "xorcc", "1id"},
+	{FORMAT3(2, OP3_X(2,3), 0), "tsubcctv", "12d"},
+	{FORMAT3(2, OP3_X(2,3), 1), "tsubcctv", "1id"},
+	{FORMAT3(2, OP3_X(3,3), 0), "UNDEFINED", ""},
+
+	{FORMAT3(2, OP3_X(0,4), 0), "sub", "12d"},
+	{FORMAT3(2, OP3_X(0,4), 1), "sub", "1id"},
+	{FORMAT3(2, OP3_X(1,4), 0), "subcc", "12d"},
+	{FORMAT3(2, OP3_X(1,4), 1), "subcc", "1id"},
+	{FORMAT3(2, OP3_X(2,4), 0), "mulscc", "12d"},
+	{FORMAT3(2, OP3_X(2,4), 1), "mulscc", "1id"},
+	{FORMAT3(2, OP3_X(3,4), 1), "FPop1", ""},	/* see below */
+
+	{FORMAT3(2, OP3_X(0,5), 0), "andn", "12d"},
+	{FORMAT3(2, OP3_X(0,5), 1), "andn", "1id"},
+	{FORMAT3(2, OP3_X(1,5), 0), "andncc", "12d"},
+	{FORMAT3(2, OP3_X(1,5), 1), "andncc", "1id"},
+	{FORMAT3(2, OP3_X(2,5), 0), "sll", "12d"},
+	{FORMAT3(2, OP3_X(2,5), 1), "sll", "1Dd"},
+	{FORMAT3(2, OP3_X(2,5), 0) | EIF_F3_X(1), "sllx", "12d"},
+	{FORMAT3(2, OP3_X(2,5), 1) | EIF_F3_X(1), "sllx", "1Ed"},
+	{FORMAT3(2, OP3_X(3,5), 1), "FPop2", ""},	/* see below */
+
+	{FORMAT3(2, OP3_X(0,6), 0), "orn", "12d"},
+	{FORMAT3(2, OP3_X(0,6), 1), "orn", "1id"},
+	{FORMAT3(2, OP3_X(1,6), 0), "orncc", "12d"},
+	{FORMAT3(2, OP3_X(1,6), 1), "orncc", "1id"},
+	{FORMAT3(2, OP3_X(2,6), 0), "srl", "12d"},
+	{FORMAT3(2, OP3_X(2,6), 1), "srl", "1Dd"},
+	{FORMAT3(2, OP3_X(2,6), 0) | EIF_F3_X(1), "srlx", "12d"},
+	{FORMAT3(2, OP3_X(2,6), 1) | EIF_F3_X(1), "srlx", "1Ed"},
+	{FORMAT3(2, OP3_X(3,6), 1), "impdep1", ""},
+
+	{FORMAT3(2, OP3_X(0,7), 0), "xorn", "12d"},
+	{FORMAT3(2, OP3_X(0,7), 1), "xorn", "1id"},
+	{FORMAT3(2, OP3_X(1,7), 0), "xorncc", "12d"},
+	{FORMAT3(2, OP3_X(1,7), 1), "xorncc", "1id"},
+	{FORMAT3(2, OP3_X(2,7), 0), "sra", "12d"},
+	{FORMAT3(2, OP3_X(2,7), 1), "sra", "1Dd"},
+	{FORMAT3(2, OP3_X(2,7), 0) | EIF_F3_X(1), "srax", "12d"},
+	{FORMAT3(2, OP3_X(2,7), 1) | EIF_F3_X(1), "srax", "1Ed"},
+	{FORMAT3(2, OP3_X(3,7), 1), "impdep2", ""},
+
+	{FORMAT3(2, OP3_X(0,8), 0), "addc", "12d"},
+	{FORMAT3(2, OP3_X(0,8), 1), "addc", "1id"},
+	{FORMAT3(2, OP3_X(1,8), 0), "addccc", "12d"},
+	{FORMAT3(2, OP3_X(1,8), 1), "addccc", "1id"},
+	{(FORMAT3(2, 0x28, 1) | EIF_F3_RS1(15)), "membar", "9"},
+	{(FORMAT3(2, 0x28, 0) | EIF_F3_RS1(15)), "stbar", ""},
+	{FORMAT3(2, OP3_X(2,8), 0), "rd", "Bd"},
+
+	{FORMAT3(2, OP3_X(3,8), 0), "jmpl", "pd"},
+	{FORMAT3(2, OP3_X(3,8), 1), "jmpl", "qd"},
+
+	{FORMAT3(2, OP3_X(0,9), 0), "mulx", "12d"},
+	{FORMAT3(2, OP3_X(0,9), 1), "mulx", "1id"},
+	{FORMAT3(2, OP3_X(1,9), 0), "UNDEFINED", ""},
+	{FORMAT3(2, OP3_X(2,9), 0), "UNDEFINED", ""},
+	{FORMAT3(2, OP3_X(3,9), 0), "return", "p"},
+	{FORMAT3(2, OP3_X(3,9), 1), "return", "q"},
+
+	{FORMAT3(2, OP3_X(0,10), 0), "umul", "12d"},
+	{FORMAT3(2, OP3_X(0,10), 1), "umul", "1id"},
+	{FORMAT3(2, OP3_X(1,10), 0), "umulcc", "12d"},
+	{FORMAT3(2, OP3_X(1,10), 1), "umulcc", "1id"},
+	{FORMAT3(2, OP3_X(2,10), 0), "rdpr", "Ad"},
+		/*
+		 * OP3 = (3,10): TCC: Trap on Integer Condition Codes
+		 */
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x8)), "ta", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x8)), "ta", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x0)), "tn", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x0)), "tn", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x9)), "tne", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x9)), "tne", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x1)), "te", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x1)), "te", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xa)), "tg", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xa)), "tg", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x2)), "tle", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x2)), "tle", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xb)), "tge", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xb)), "tge", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x3)), "tl", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x3)), "tl", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xc)), "tgu", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xc)), "tgu", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x4)), "tleu", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x4)), "tleu", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xd)), "tcc", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xd)), "tcc", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x5)), "tcs", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x5)), "tcs", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xe)), "tpos", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xe)), "tpos", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x6)), "tneg", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x6)), "tneg", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xf)), "tvc", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xf)), "tvc", "0F"},
+		{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x7)), "tvs", "12F"},
+		{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x7)), "tvs", "0F"},
+
+	{FORMAT3(2, OP3_X(0,11), 0), "smul", "12d"},
+	{FORMAT3(2, OP3_X(0,11), 1), "smul", "1id"},
+	{FORMAT3(2, OP3_X(1,11), 0), "smulcc", "12d"},
+	{FORMAT3(2, OP3_X(1,11), 1), "smulcc", "1id"},
+	{FORMAT3(2, OP3_X(2,11), 0), "flushw", ""},
+	{FORMAT3(2, OP3_X(3,11), 0), "flush", "p"},
+	{FORMAT3(2, OP3_X(3,11), 1), "flush", "q"},
+
+	{FORMAT3(2, OP3_X(0,12), 0), "subc", "12d"},
+	{FORMAT3(2, OP3_X(0,12), 1), "subc", "1id"},
+	{FORMAT3(2, OP3_X(1,12), 0), "subccc", "12d"},
+	{FORMAT3(2, OP3_X(1,12), 1), "subccc", "1id"},
+		/*
+		 * OP3 = (2,12): MOVcc, Move Integer Register on Condition
+		 */
+		/* For Integer Condition Codes */
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,8)), "mova", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,8)), "mova", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,0)), "movn", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,0)), "movn", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,9)), "movne", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,9)), "movne", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,1)), "move", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,1)), "move", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,10)), "movg", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,10)), "movg", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,2)), "movle", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,2)), "movle", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,11)), "movge", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,11)), "movge", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,3)), "movl", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,3)), "movl", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,12)), "movgu", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,12)), "movgu", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,4)), "movleu", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,4)), "movleu", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,13)), "movcc", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,13)), "movcc", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,5)), "movcs", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,5)), "movcs", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,14)), "movpos", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,14)), "movpos", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,6)), "movneg", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,6)), "movneg", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,15)), "movvc", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,15)), "movvc", "02d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(1,7)), "movvs", "0jd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(1,7)), "movvs", "02d"},
+
+		/* For Floating-Point Condition Codes */
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,8)), "mova", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,8)), "mova", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,0)), "movn", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,0)), "movn", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,7)), "movu", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,7)), "movu", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,6)), "movg", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,6)), "movg", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,5)), "movug", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,5)), "movug", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,4)), "movl", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,4)), "movl", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,3)), "movul", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,3)), "movul", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,2)), "movlg", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,2)), "movlg", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,1)), "movne", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,1)), "movne", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,9)), "move", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,9)), "move", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,10)), "movue", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,10)), "movue", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,11)), "movge", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,11)), "movge", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,12)), "movuge", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,12)), "movuge", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,13)), "movle", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,13)), "movle", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,14)), "movule", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,14)), "movule", "o2d"},
+		{(FORMAT3(2, OP3_X(2,12), 1) | COND2(0,15)), "movo", "ojd"},
+		{(FORMAT3(2, OP3_X(2,12), 0) | COND2(0,15)), "movo", "o2d"},
+
+	{FORMAT3(2, OP3_X(3,12), 0), "save", "12d"},
+	{FORMAT3(2, OP3_X(3,12), 1), "save", "1id"},
+
+	{FORMAT3(2, OP3_X(0,13), 0), "udivx", "12d"},
+	{FORMAT3(2, OP3_X(0,13), 1), "udivx", "1id"},
+	{FORMAT3(2, OP3_X(1,13), 0), "UNDEFINED", ""},
+	{FORMAT3(2, OP3_X(2,13), 0), "sdivx", "12d"},
+	{FORMAT3(2, OP3_X(2,13), 1), "sdivx", "1id"},
+	{FORMAT3(2, OP3_X(3,13), 0), "restore", "12d"},
+	{FORMAT3(2, OP3_X(3,13), 1), "restore", "1id"},
+
+	{FORMAT3(2, OP3_X(0,14), 0), "udiv", "12d"},
+	{FORMAT3(2, OP3_X(0,14), 1), "udiv", "1id"},
+	{FORMAT3(2, OP3_X(1,14), 0), "udivcc", "12d"},
+	{FORMAT3(2, OP3_X(1,14), 1), "udivcc", "1id"},
+	{FORMAT3(2, OP3_X(2,14), 0), "popc", "2d"},
+	{FORMAT3(2, OP3_X(2,14), 1), "popc", "id"},
+
+	{FORMAT3(2, OP3_X(3,14), 0), "done", ""},
+	{FORMAT3(2, OP3_X(3,14) | EIF_F3_FCN(1), 1), "retry", ""},
+
+	{FORMAT3(2, OP3_X(0,15), 0), "sdiv", "12d"},
+	{FORMAT3(2, OP3_X(0,15), 1), "sdiv", "1id"},
+	{FORMAT3(2, OP3_X(1,15), 0), "sdivcc", "12d"},
+	{FORMAT3(2, OP3_X(1,15), 1), "sdivcc", "1id"},
+		/*
+		 * OP3 = (2,15): MOVr:
+		 * 	Move Integer Register on Register Condition
+		 */
+		{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(1)), "movrz", "1jd"},
+		{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(1)), "movrz", "12d"},
+		{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(2)), "movrlez", "1jd"},
+		{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(2)), "movrlez", "12d"},
+		{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(3)), "movrlz", "1jd"},
+		{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(3)), "movrlz", "12d"},
+		{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(5)), "movrnz", "1jd"},
+		{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(5)), "movrnz", "12d"},
+		{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(6)), "movrgz", "1jd"},
+		{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(6)), "movrgz", "12d"},
+		{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(7)), "movrgez", "1jd"},
+		{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(7)), "movrgez", "12d"},
+
+	{FORMAT3(2, OP3_X(3,15), 0), "UNDEFINED", ""},
+
+
+	/*
+	 * Format 3/3: Load and store (appendix E, table 33)
+	 */
+
+	/* Loads */
+	{(FORMAT3(3, OP3_X(0,0), 0)), "lduw", "pd"},
+	{(FORMAT3(3, OP3_X(0,0), 1)), "lduw", "qd"},
+	{(FORMAT3(3, OP3_X(1,0), 0)), "lduwa", "7d"},
+	{(FORMAT3(3, OP3_X(1,0), 1)), "lduwa", "8d"},
+	{(FORMAT3(3, OP3_X(2,0), 0)), "ldf", "pe"},
+	{(FORMAT3(3, OP3_X(2,0), 1)), "ldf", "qe"},
+	{(FORMAT3(3, OP3_X(3,0), 0)), "ldfa", "7e"},
+	{(FORMAT3(3, OP3_X(3,0), 1)), "ldfa", "8e"},
+
+	{(FORMAT3(3, OP3_X(0,1), 0)), "ldub", "pd"},
+	{(FORMAT3(3, OP3_X(0,1), 1)), "ldub", "qd"},
+	{(FORMAT3(3, OP3_X(1,1), 0)), "lduba", "7d"},
+	{(FORMAT3(3, OP3_X(1,1), 1)), "lduba", "8d"},
+	{(FORMAT3(3, OP3_X(2,1), 0) | EIF_F3_RD(0)), "lduw", "p5"},
+	{(FORMAT3(3, OP3_X(2,1), 1) | EIF_F3_RD(0)), "lduw", "q5"},
+	{(FORMAT3(3, OP3_X(2,1), 0) | EIF_F3_RD(1)), "ldx", "p6"},
+	{(FORMAT3(3, OP3_X(2,1), 1) | EIF_F3_RD(1)), "ldx", "q6"},
+
+	{(FORMAT3(3, OP3_X(0,2), 0)), "lduh", "pd"},
+	{(FORMAT3(3, OP3_X(0,2), 1)), "lduh", "qd"},
+	{(FORMAT3(3, OP3_X(1,2), 0)), "lduha", "7d"},
+	{(FORMAT3(3, OP3_X(1,2), 1)), "lduha", "8d"},
+	{(FORMAT3(3, OP3_X(2,2), 0)), "ldq", "pe"},
+	{(FORMAT3(3, OP3_X(2,2), 1)), "ldq", "qe"},
+	{(FORMAT3(3, OP3_X(3,2), 0)), "ldqa", "7e"},
+	{(FORMAT3(3, OP3_X(3,2), 1)), "ldqa", "8e"},
+
+	{(FORMAT3(3, OP3_X(0,3), 0)), "ldd", "pd"},
+	{(FORMAT3(3, OP3_X(0,3), 1)), "ldd", "qd"},
+	{(FORMAT3(3, OP3_X(1,3), 0)), "ldda", "7d"},
+	{(FORMAT3(3, OP3_X(1,3), 1)), "ldda", "8d"},
+	{(FORMAT3(3, OP3_X(2,3), 0)), "ldd", "pe"},
+	{(FORMAT3(3, OP3_X(2,3), 1)), "ldd", "qe"},
+	{(FORMAT3(3, OP3_X(3,3), 0)), "ldda", "7e"},
+	{(FORMAT3(3, OP3_X(3,3), 1)), "ldda", "8e"},
+
+	{(FORMAT3(3, OP3_X(0,4), 0)), "stw", "dp"},
+	{(FORMAT3(3, OP3_X(0,4), 1)), "stw", "dq"},
+	{(FORMAT3(3, OP3_X(1,4), 0)), "stwa", "d7"},
+	{(FORMAT3(3, OP3_X(1,4), 1)), "stwa", "d8"},
+	{(FORMAT3(3, OP3_X(2,4), 0)), "stf", "ep"},
+	{(FORMAT3(3, OP3_X(2,4), 1)), "stf", "eq"},
+	{(FORMAT3(3, OP3_X(3,4), 0)), "stfa", "e7"},
+	{(FORMAT3(3, OP3_X(3,4), 1)), "stfa", "e8"},
+
+	{(FORMAT3(3, OP3_X(0,5), 0)), "stb", "dp"},
+	{(FORMAT3(3, OP3_X(0,5), 1)), "stb", "dq"},
+	{(FORMAT3(3, OP3_X(1,5), 0)), "stba", "d7"},
+	{(FORMAT3(3, OP3_X(1,5), 1)), "stba", "d8"},
+	{(FORMAT3(3, OP3_X(2,5), 0)), "stw", "5p"},
+	{(FORMAT3(3, OP3_X(2,5), 1)), "stw", "5q"},
+	{(FORMAT3(3, OP3_X(2,5), 0) | EIF_F3_RD(1)), "stx", "6p"},
+	{(FORMAT3(3, OP3_X(2,5), 1) | EIF_F3_RD(1)), "stx", "6q"},
+
+	{(FORMAT3(3, OP3_X(0,6), 0)), "sth", "dp"},
+	{(FORMAT3(3, OP3_X(0,6), 1)), "sth", "dq"},
+	{(FORMAT3(3, OP3_X(1,6), 0)), "stha", "d7"},
+	{(FORMAT3(3, OP3_X(1,6), 1)), "stha", "d8"},
+	{(FORMAT3(3, OP3_X(2,6), 0)), "stq", "ep"},
+	{(FORMAT3(3, OP3_X(2,6), 1)), "stq", "eq"},
+	{(FORMAT3(3, OP3_X(3,6), 0)), "stqa", "e7"},
+	{(FORMAT3(3, OP3_X(3,6), 1)), "stqa", "e8"},
+
+	{(FORMAT3(3, OP3_X(0,7), 0)), "std", "dp"},
+	{(FORMAT3(3, OP3_X(0,7), 1)), "std", "dq"},
+	{(FORMAT3(3, OP3_X(1,7), 0)), "stda", "d7"},
+	{(FORMAT3(3, OP3_X(1,7), 1)), "stda", "d8"},
+	{(FORMAT3(3, OP3_X(2,7), 0)), "std", "ep"},
+	{(FORMAT3(3, OP3_X(2,7), 1)), "std", "eq"},
+	{(FORMAT3(3, OP3_X(3,7), 0)), "stda", "e7"},
+	{(FORMAT3(3, OP3_X(3,7), 1)), "stda", "e8"},
+
+	{(FORMAT3(3, OP3_X(0,8), 0)), "ldsw", "pd"},
+	{(FORMAT3(3, OP3_X(0,8), 1)), "ldsw", "qd"},
+	{(FORMAT3(3, OP3_X(1,8), 0)), "ldswa", "7d"},
+	{(FORMAT3(3, OP3_X(1,8), 1)), "ldswa", "8d"},
+
+	{(FORMAT3(3, OP3_X(0,9), 0)), "ldsb", "pd"},
+	{(FORMAT3(3, OP3_X(0,9), 1)), "ldsb", "qd"},
+	{(FORMAT3(3, OP3_X(1,9), 0)), "ldsba", "7d"},
+	{(FORMAT3(3, OP3_X(1,9), 1)), "ldsba", "8d"},
+
+	{(FORMAT3(3, OP3_X(0,10), 0)), "ldsh", "pd"},
+	{(FORMAT3(3, OP3_X(0,10), 1)), "ldsh", "qd"},
+	{(FORMAT3(3, OP3_X(1,10), 0)), "ldsha", "7d"},
+	{(FORMAT3(3, OP3_X(1,10), 1)), "ldsha", "8d"},
+
+	{(FORMAT3(3, OP3_X(0,11), 0)), "ldx", "pd"},
+	{(FORMAT3(3, OP3_X(0,11), 1)), "ldx", "qd"},
+	{(FORMAT3(3, OP3_X(1,11), 0)), "ldxa", "7d"},
+	{(FORMAT3(3, OP3_X(1,11), 1)), "ldxa", "8d"},
+
+	{(FORMAT3(3, OP3_X(3,12), 1)), "casa", "s2d"},
+	{(FORMAT3(3, OP3_X(3,12), 0)), "casa", "t2d"},
+
+	{(FORMAT3(3, OP3_X(0,13), 0)), "ldstub", "7d"},
+	{(FORMAT3(3, OP3_X(0,13), 1)), "ldstub", "8d"},
+	{(FORMAT3(3, OP3_X(1,13), 0)), "ldstuba", "pd"},
+	{(FORMAT3(3, OP3_X(1,13), 1)), "ldstuba", "qd"},
+	{(FORMAT3(3, OP3_X(2,13), 0)), "prefetch", "pr"},
+	{(FORMAT3(3, OP3_X(2,13), 1)), "prefetch", "qr"},
+	{(FORMAT3(3, OP3_X(3,13), 0)), "prefetcha", "7r"},
+	{(FORMAT3(3, OP3_X(3,13), 1)), "prefetcha", "8r"},
+
+	{(FORMAT3(3, OP3_X(0,14), 0)), "stx", "dp"},
+	{(FORMAT3(3, OP3_X(0,14), 1)), "stx", "dq"},
+	{(FORMAT3(3, OP3_X(1,14), 0)), "stxa", "d7"},
+	{(FORMAT3(3, OP3_X(1,14), 1)), "stxa", "d8"},
+	{(FORMAT3(3, OP3_X(3,14), 0)), "casxa", "t2d"},
+	{(FORMAT3(3, OP3_X(3,14), 1)), "casxa", "s2d"},
+
+	/* Swap Register */
+	{(FORMAT3(3, OP3_X(0,15), 0)), "swap", "pd"},
+	{(FORMAT3(3, OP3_X(0,15), 1)), "swap", "qd"},
+	{(FORMAT3(3, OP3_X(1,15), 0)), "swapa", "7d"},
+	{(FORMAT3(3, OP3_X(1,15), 1)), "swapa", "8d"},
+
+
+	/*
+	 * OP3 = (3,4): FPop1 (table 34)
+	 */
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,1))), "fmovs", ".4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,2))), "fmovd", ".4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,3))), "fmovq", ".4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,5))), "fnegs", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,6))), "fnegd", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,7))), "fnegq", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,9))), "fabss", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,10))), "fabsd", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(0,11))), "fabsq", "4e"},
+
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(2,9))), "fsqrts", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(2,10))), "fsqrtd", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(2,11))), "fsqrtq", "4e"},
+
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,1))), "fadds", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,2))), "faddd", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,3))), "faddq", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,5))), "fsubs", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,6))), "fsubd", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,7))), "fsubq", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,9))), "fmuls", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,10))), "fmuld", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,11))), "fmulq", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,13))), "fdivs", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,14))), "fdivd", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(4,15))), "fdivq", "34e"},
+
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(6,9))), "fsmuld", "34e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(6,14))), "fdmulq", "34e"},
+
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,1))), "fstox", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,2))), "fdtox", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,3))), "fqtox", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,4))), "fxtos", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,8))), "fxtod", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(8,12))), "fxtoq", "4e"},
+
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,4))), "fitos", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,6))), "fdtos", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,7))), "fqtos", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,8))), "fitod", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,9))), "fstod", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,11))), "fqtod", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,12))), "fitoq", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,13))), "fstoq", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(12,14))), "fdtoq", "4e"},
+
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(13,1))), "fstoi", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(13,2))), "fdtoi", "4e"},
+	{(FORMAT3F(2, OP3_X(3,4), OPF_X(13,3))), "fqtoi", "4e"},
+
+
+#ifdef xxx
+	/*
+	 * OP3 =(3,5): FPop2 (table 35)
+	 */
+	{(FORMAT3F(2, OP3_X(3,5), 81)), "fcmps", "o34"},
+	{(FORMAT3F(2, OP3_X(3,5), 82)), "fcmpd", "o34"},
+	{(FORMAT3F(2, OP3_X(3,5), 83)), "fcmpq", "o34"},
+	{(FORMAT3F(2, OP3_X(3,5), 85)), "fcmpes", "o34"},
+	{(FORMAT3F(2, OP3_X(3,5), 86)), "fcmped", "o34"},
+	{(FORMAT3F(2, OP3_X(3,5), 87)), "fcmpeq", "o34"},
+
+	/* Move Floating-Point Register on Condition "FMOVcc" */
+	/* FIXME should check for single, double, and quad movements */
+	/* Integer Condition Codes */
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,8)), "fmova", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,0)), "fmovn", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,9)), "fmovne", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,1)), "fmove", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,10)), "fmovg", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,2)), "fmovle", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,11)), "fmovge", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,3)), "fmovl", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,12)), "fmovgu", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,4)), "fmovleu", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,13)), "fmovcc", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,5)), "fmovcs", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,14)), "fmovpos", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,6)), "fmovneg", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,15)), "fmovvc", "04e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,7)), "fmovvs", "04e"},
+
+	/* Floating-Point Condition Codes */
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,8)), "fmova", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,0)), "fmovn", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,7)), "fmovu", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,6)), "fmovg", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,5)), "fmovug", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,4)), "fmovk", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,3)), "fmovul", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,2)), "fmovlg", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,1)), "fmovne", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,9)), "fmove", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,10)), "fmovue", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,11)), "fmovge", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,12)), "fmovuge", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,13)), "fmovle", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,14)), "fmovule", "o4e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | COND2(0,15)), "fmovo", "o4e"},
+
+	/* Move F-P Register on Integer Register Condition "FMOVr" */
+	/* FIXME: check for short, double, and quad's */
+	{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(1)), "fmovre", "14e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(2)), "fmovrlez", "14e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(3)), "fmovrlz", "14e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(5)), "fmovrne", "14e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(6)), "fmovrgz", "14e"},
+	{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(7)), "fmovrgez", "14e"},
+#endif
+	/* FP logical insns -- UltraSPARC extens */
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,0))), "fzero", "e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,1))), "fzeros", "e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,14))), "fone", "e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,15))), "fones", "e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,4))), "fsrc1", "3e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,5))), "fsrc1s", "3e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,8))), "fsrc2", "4e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,9))), "fsrc2s", "4e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,10))), "fnot1", "3e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,11))), "fnot1s", "3e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,6))), "fnot2", "4e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,7))), "fnot2s", "4e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,12))), "for", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,13))), "fors", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,2))), "fnor", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,3))), "fnors", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,0))), "fand", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,1))), "fands", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,14))), "fnand", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,15))), "fnands", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,12))), "fxor", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,13))), "fxors", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,2))), "fxnor", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,3))), "fxnors", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,10))), "fornot1", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,11))), "fornot1s", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,6))), "fornot2", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(7,7))), "fornot2s", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,8))), "fandnot1", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,9))), "fandnot1s", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,4))), "fandnot2", "34e"},
+	{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,5))), "fandnot2s", "34e"},
+
+	/* grrrr.... */
+	{0, 0, 0}
+
+};
+
+db_addr_t
+db_disasm(db_addr_t loc, boolean_t altfmt)
+{
+	const struct sparc_insn* i_ptr = (struct sparc_insn *)&sparc_i;
+	unsigned int insn, you_lose, bitmask;
+	int matchp;
+	const char* f_ptr, *cp;
+
+	you_lose = 0;
+	matchp = 0;
+	insn = db_get_value(loc, 4, 0);
+
+	if (insn == 0x01000000) {
+		db_printf("nop\n");
+		return loc + 4;
+	}
+
+	while (i_ptr->name) {
+		/* calculate YOU_LOSE value */
+		bitmask= (i_ptr->match);
+		you_lose = (~bitmask);
+
+		if (((bitmask>>30) & 0x3) == 0x1) {
+			/* Call */
+			you_lose = ((~0x1)<<30);
+		} else if (((bitmask>>30) & 0x3) == 0x0) {
+			if (((bitmask>>22) & 0x7) == 0x4) {
+				/* Sethi */
+				you_lose &= (FORMAT2(0x3,0x7));
+			} else {
+				/* Branches */
+				you_lose &= (FORMAT2(0x3,0x7) |
+				    EIF_F2_COND(0xf));
+			}
+		} else if (((bitmask>>30) & 0x3) == 0x2 &&
+			   ((bitmask>>19) & 0x3f) == 0x34) /* XXX */ {
+			/* FPop1 */
+			you_lose &= (FORMAT3(0x3,0x3f,0x1) |
+			    EIF_F3_OPF(0x1ff));
+		} else if (((bitmask>>30) & 0x3) == 0x2 &&
+			   ((bitmask>>19) & 0x3f) == 0x3a) /* XXX */ {
+			/* Tcc */
+			you_lose &= (FORMAT3(0x3,0x3f,0x1) | EIF_F4_TCOND(0xf));
+		} else if (((bitmask>>30) & 0x3) == 0x2 &&
+			   ((bitmask>>21) & 0xf) == 0x9 &&
+			   ((bitmask>>19) & 0x3) != 0) /* XXX */ {
+			/* shifts */
+			you_lose &= (FORMAT3(0x3,0x3f,0x1)) | EIF_F3_X(1);
+		} else if (((bitmask>>30) & 0x3) == 0x2 &&
+			   ((bitmask>>19) & 0x3f) == 0x2c) /* XXX */ {
+			/* cmov */
+			you_lose &= (FORMAT3(0x3,0x3f,0x1) | COND2(1,0xf));
+		} else if (((bitmask>>30) & 0x3) == 0x2 &&
+			   ((bitmask>>19) & 0x3f) == 0x35) /* XXX */ {
+			/* fmov */
+			you_lose &= (FORMAT3(0x3,0x3f,0x1) | COND2(1,0xf));
+		} else {
+			you_lose &= (FORMAT3(0x3,0x3f,0x1));
+		}
+
+		if (((bitmask & insn) == bitmask) && ((you_lose & insn) == 0)) {
+			matchp = 1;
+			break;
+		}
+		i_ptr++;
+	};
+
+	if (!matchp) {
+		db_printf("undefined\n");
+		return loc + 4;
+	}
+
+	db_printf("%s", i_ptr->name);
+
+	f_ptr = i_ptr->format;
+
+	for (cp = f_ptr; *cp; cp++) {
+		if (*cp == ',') {
+			for (;f_ptr < cp; f_ptr++)
+				switch (*f_ptr) {
+				case 'a':
+					if (insn & EIF_F2_A(1))
+						db_printf(",a");
+					break;
+				case 'p':
+					if (insn & EIF_F2_P(1))
+						db_printf(",pt");
+					else
+						db_printf(",pn");
+					break;
+				}
+			f_ptr++;
+			break;
+		}
+	}
+	db_printf("      \t");
+
+	while (*f_ptr) {
+		switch (*f_ptr) {
+			int64_t val;
+		case '1':
+			db_printf("%%%s", regs[((insn >> 14) & 0x1f)]);
+			break;
+		case '2':
+			db_printf("%%%s", regs[(insn & 0x1f)]);
+			break;
+		case 'd':
+			db_printf("%%%s", regs[((insn >> 25) & 0x1f)]);
+			break;
+		case '3':
+			db_printf("%%f%d", ((insn >> 14) & 0x1f));
+			break;
+		case '4':
+			db_printf("%%f%d", (insn & 0x1f));
+			break;
+		case 'e':
+			db_printf("%%f%d", ((insn >> 25) & 0x1f));
+			break;
+		case 'i':
+			/* simm13 -- signed */
+			val = IF_SIMM(insn, 13);
+			db_printf("%s0x%x", SIGN(val), (int)abs(val));
+			break;
+		case 'j':
+			/* simm11 -- signed */
+			val = IF_SIMM(insn, 11);
+			db_printf("%s0x%x", SIGN(val), (int)abs(val));
+			break;
+		case 'l':
+			val = (((insn>>20)&0x3)<<13)|(insn & 0x1fff);
+			val = IF_SIMM(val, 16);
+			db_printsym((db_addr_t)(loc + (4 * val)), DB_STGY_ANY);
+			break;
+		case 'm':
+			db_printsym((db_addr_t)(loc + (4 * IF_SIMM(insn, 22))),
+				DB_STGY_ANY);
+			break;
+		case 'u':
+			db_printsym((db_addr_t)(loc + (4 * IF_SIMM(insn, 19))),
+			    DB_STGY_ANY);
+			break;
+		case 'n':
+			db_printsym((db_addr_t)(loc + (4 * IF_SIMM(insn, 30))),
+			    DB_STGY_PROC);
+			break;
+		case 's':
+			db_printf("%%asi");
+			break;
+		case 't':
+			db_printf("0x%-2.2x", ((insn >> 5) & 0xff));
+			break;
+		case 'o':
+			db_printf("%%fcc%d", ((insn >> 25) & 0x3));
+			break;
+		case 'p':
+		case '7':
+			db_printf("[%%%s + %%%s]",
+				  regs[((insn >> 14) & 0x1f)],
+				  regs[(insn & 0x1f)]);
+			if (*f_ptr == '7')
+				db_printf(" %d", ((insn >> 5) & 0xff));
+			break;
+		case 'q':
+		case '8':
+			val = IF_SIMM(insn, 13);
+			db_printf("[%%%s %c 0x%x]",
+				regs[((insn >> 14) & 0x1f)],
+				(int)((val<0)?'-':'+'),
+				(int)abs(val));
+			if (*f_ptr == '8')
+				db_printf(" %%asi");
+			break;
+		case '5':
+			db_printf("%%fsr");
+			break;
+		case '6':
+			db_printf("%%fsr");
+			break;
+		case '9':
+			db_printf("0x%xl",
+				  ((insn & 0xf) | ((insn >> 4) & 0x7)));
+			break;
+		case '0':
+			db_printf("%%%s", ccodes[((insn >> 11) & 0x3) + 4]);
+			break;
+		case '.':
+			db_printf("%%%s", ccodes[((insn >> 11) & 0x7)]);
+			break;
+		case 'r':
+			db_printf("#%s", prefetch[((insn >> 25) & 0x1f)]);
+			break;
+		case 'A':
+			db_printf("%%%s", priv_regs[((insn >> 14) & 0x1f)]);
+			break;
+		case 'B':
+			db_printf("%%%s", state_regs[((insn >> 14) & 0x1f)]);
+			break;
+		case 'C':
+			db_printf("%%hi(0x%x)", ((insn & 0x3fffff) << 10));
+			break;
+		case 'D':
+			db_printf("0x%x", (insn & 0x1f));
+			break;
+		case 'E':
+			db_printf("%d", (insn & 0x3f));
+			break;
+		case 'F':
+			db_printf("%d", (insn & 0x3f));
+			break;
+		case 'G':
+			db_printf("%%%s", priv_regs[((insn >> 25) & 0x1f)]);
+			break;
+		case 'H':
+			db_printf("%%%s", state_regs[((insn >> 25) & 0x1f)]);
+			break;
+		default:
+			db_printf("(UNKNOWN)");
+			break;
+		}
+		if (*(++f_ptr))
+			db_printf(", ");
+	};
+
+	db_printf("\n");
+
+	return (loc + 4);
+}


Property changes on: trunk/sys/sparc64/sparc64/db_disasm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/db_hwwatch.c
===================================================================
--- trunk/sys/sparc64/sparc64/db_hwwatch.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/db_hwwatch.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,212 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * All rights reserved.
+ * Copyright 2001 by Thomas Moestl <tmm at 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, 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/sparc64/db_hwwatch.c 149925 2005-09-10 03:01:25Z marcel $
+ */
+
+#include <sys/param.h>
+
+#include <vm/vm.h>
+
+#include <machine/asi.h>
+#include <machine/cpufunc.h>
+#include <machine/lsu.h>
+#include <machine/watch.h>
+
+#include <ddb/ddb.h>
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_variables.h>
+#include <ddb/db_watch.h>
+
+static void db_watch_print(vm_offset_t wp, int bm);
+
+int
+watch_phys_set_mask(vm_paddr_t pa, u_long mask)
+{
+	u_long lsucr;
+
+	stxa_sync(AA_DMMU_PWPR, ASI_DMMU, pa & (((2UL << 38) - 1) << 3));
+	lsucr = ldxa(0, ASI_LSU_CTL_REG);
+	lsucr = ((lsucr | LSU_PW) & ~LSU_PM_MASK) |
+	    (mask << LSU_PM_SHIFT);
+	stxa_sync(0, ASI_LSU_CTL_REG, lsucr);
+	return (0);
+}
+
+int
+watch_phys_set(vm_paddr_t pa, int sz)
+{
+	u_long off;
+
+	off = (u_long)pa & 7;
+	/* Test for misaligned watch points. */
+	if (off + sz > 8)
+		return (-1);
+	return (watch_phys_set_mask(pa, ((1 << sz) - 1) << off));
+}
+
+vm_paddr_t
+watch_phys_get(int *bm)
+{
+	vm_paddr_t pa;
+	u_long lsucr;
+	
+	if (!watch_phys_active())
+		return (0);
+
+	pa = ldxa(AA_DMMU_PWPR, ASI_DMMU);
+	lsucr = ldxa(0, ASI_LSU_CTL_REG);
+	*bm = (lsucr & LSU_PM_MASK) >> LSU_PM_SHIFT;
+	
+	return (pa);
+}
+
+void
+watch_phys_clear()
+{
+	stxa_sync(0, ASI_LSU_CTL_REG,
+	    ldxa(0, ASI_LSU_CTL_REG) & ~LSU_PW);
+}
+
+int
+watch_phys_active()
+{
+
+	return (ldxa(0, ASI_LSU_CTL_REG) & LSU_PW);
+}
+
+int
+watch_virt_set_mask(vm_offset_t va, u_long mask)
+{
+	u_long lsucr;
+
+	stxa_sync(AA_DMMU_VWPR, ASI_DMMU, va & (((2UL << 41) - 1) << 3));
+	lsucr = ldxa(0, ASI_LSU_CTL_REG);
+	lsucr = ((lsucr | LSU_VW) & ~LSU_VM_MASK) |
+	    (mask << LSU_VM_SHIFT);
+	stxa_sync(0, ASI_LSU_CTL_REG, lsucr);
+	return (0);
+}
+
+int
+watch_virt_set(vm_offset_t va, int sz)
+{
+	u_long off;
+
+	off = (u_long)va & 7;
+	/* Test for misaligned watch points. */
+	if (off + sz > 8)
+		return (-1);
+	return (watch_virt_set_mask(va, ((1 << sz) - 1) << off));
+}
+
+vm_offset_t
+watch_virt_get(int *bm)
+{
+	u_long va;
+	u_long lsucr;
+	
+	if (!watch_virt_active())
+		return (0);
+
+	va = ldxa(AA_DMMU_VWPR, ASI_DMMU);
+	lsucr = ldxa(0, ASI_LSU_CTL_REG);
+	*bm = (lsucr & LSU_VM_MASK) >> LSU_VM_SHIFT;
+	
+	return ((vm_offset_t)va);
+}
+
+void
+watch_virt_clear()
+{
+	stxa_sync(0, ASI_LSU_CTL_REG,
+	    ldxa(0, ASI_LSU_CTL_REG) & ~LSU_VW);
+}
+
+int
+watch_virt_active()
+{
+
+	return (ldxa(0, ASI_LSU_CTL_REG) & LSU_VW);
+}
+
+int
+db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
+{
+	int dummy;
+
+	if (watch_virt_active()) {
+		db_printf("Overwriting previously active watch point at "
+		    "0x%lx\n", watch_virt_get(&dummy));
+	}
+	return (watch_virt_set(addr, size));
+}
+
+int
+db_md_clr_watchpoint(db_expr_t addr, db_expr_t size)
+{
+
+	watch_virt_clear();
+	return (0);
+}
+
+void
+db_watch_print(vm_offset_t wp, int bm)
+{
+	int i;
+
+	db_printf("\tat 0x%lx, active bytes: ", (u_long)wp);
+	for (i = 0; i < 8; i++) {
+		if ((bm & (1 << i)) != 0)
+			db_printf("%d ", i);
+	}
+	if (bm == 0)
+		db_printf("none");
+	db_printf("\n");
+}
+
+void
+db_md_list_watchpoints(void)
+{
+	vm_offset_t va;
+	vm_paddr_t pa;
+	int bm;
+
+	db_printf("Physical address watchpoint:\n");
+	if (watch_phys_active()) {
+		pa = watch_phys_get(&bm);
+		db_watch_print(pa, bm);
+	} else
+		db_printf("\tnot active.\n");
+	db_printf("Virtual address watchpoint:\n");
+	if (watch_virt_active()) {
+		va = watch_virt_get(&bm);
+		db_watch_print(va, bm);
+	} else
+		db_printf("\tnot active.\n");
+}


Property changes on: trunk/sys/sparc64/sparc64/db_hwwatch.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/db_interface.c
===================================================================
--- trunk/sys/sparc64/sparc64/db_interface.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/db_interface.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,96 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/sparc64/db_interface.c 163192 2006-10-10 07:26:54Z bde $
+ */
+
+#include <sys/param.h> 
+#include <sys/systm.h>
+#include <sys/reboot.h>
+#include <sys/cons.h>
+#include <sys/kdb.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/smp.h>
+
+#include <machine/cpu.h>
+#include <machine/md_var.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <ddb/ddb.h>
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_variables.h>
+
+#include <machine/atomic.h>
+#include <machine/setjmp.h>
+
+int
+db_read_bytes(vm_offset_t addr, size_t size, char *data)
+{
+	jmp_buf jb;
+	void *prev_jb;
+	char *src;
+	int ret;
+
+	prev_jb = kdb_jmpbuf(jb);
+	ret = setjmp(jb);
+	if (ret == 0) {
+		src = (char *)addr;
+		while (size-- > 0)
+			*data++ = *src++;
+	}
+	(void)kdb_jmpbuf(prev_jb);
+	return (ret);
+}
+
+int
+db_write_bytes(vm_offset_t addr, size_t size, char *data)
+{
+	jmp_buf jb;
+	void *prev_jb;
+	char *dst;
+	int ret;
+
+	prev_jb = kdb_jmpbuf(jb);
+	ret = setjmp(jb);
+	if (ret == 0) {
+		dst = (char *)addr;
+		while (size-- > 0)
+			*dst++ = *data++;
+	}
+	(void)kdb_jmpbuf(prev_jb);
+	return (ret);
+}
+
+void
+db_show_mdpcpu(struct pcpu *pc)
+{
+}


Property changes on: trunk/sys/sparc64/sparc64/db_interface.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/db_trace.c
===================================================================
--- trunk/sys/sparc64/sparc64/db_trace.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/db_trace.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,292 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/db_trace.c 217265 2011-01-11 13:59:06Z jhb $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kdb.h>
+#include <sys/proc.h>
+#include <sys/stack.h>
+#include <sys/sysent.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+
+#include <machine/cpu.h>
+#include <machine/pcb.h>
+#include <machine/stack.h>
+#include <machine/trap.h>
+#include <machine/vmparam.h>
+
+#include <ddb/ddb.h>
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_variables.h>
+#include <ddb/db_watch.h>
+
+static db_varfcn_t db_frame;
+
+#define	DB_OFFSET(x)	(db_expr_t *)offsetof(struct trapframe, x)
+struct	db_variable db_regs[] = {
+	{ "g0",		DB_OFFSET(tf_global[0]),	db_frame },
+	{ "g1",		DB_OFFSET(tf_global[1]),	db_frame },
+	{ "g2",		DB_OFFSET(tf_global[2]),	db_frame },
+	{ "g3",		DB_OFFSET(tf_global[3]),	db_frame },
+	{ "g4",		DB_OFFSET(tf_global[4]),	db_frame },
+	{ "g5",		DB_OFFSET(tf_global[5]),	db_frame },
+	{ "g6",		DB_OFFSET(tf_global[6]),	db_frame },
+	{ "g7",		DB_OFFSET(tf_global[7]),	db_frame },
+	{ "i0",		DB_OFFSET(tf_out[0]),		db_frame },
+	{ "i1",		DB_OFFSET(tf_out[1]),		db_frame },
+	{ "i2",		DB_OFFSET(tf_out[2]),		db_frame },
+	{ "i3",		DB_OFFSET(tf_out[3]),		db_frame },
+	{ "i4",		DB_OFFSET(tf_out[4]),		db_frame },
+	{ "i5",		DB_OFFSET(tf_out[5]),		db_frame },
+	{ "i6",		DB_OFFSET(tf_out[6]),		db_frame },
+	{ "i7",		DB_OFFSET(tf_out[7]),		db_frame },
+	{ "tnpc",	DB_OFFSET(tf_tnpc),		db_frame },
+	{ "tpc",	DB_OFFSET(tf_tpc),		db_frame },
+	{ "tstate",	DB_OFFSET(tf_tstate),		db_frame },
+};
+struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+
+static int
+db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
+{
+	uint64_t *reg;
+
+	if (kdb_frame == NULL)
+		return (0);
+	reg = (uint64_t*)((uintptr_t)kdb_frame + (uintptr_t)vp->valuep);
+	if (op == DB_VAR_GET)
+		*valuep = *reg;
+	else
+		*reg = *valuep;
+	return (1);
+}
+
+/*
+ * User stack trace (debugging aid).
+ */
+static void
+db_utrace(struct thread *td, struct trapframe *tf, int count)
+{
+	struct pcb *pcb;
+	db_addr_t sp, rsp, o7, pc;
+	int i, found;
+
+	pcb = td->td_pcb;
+	sp = db_get_value((db_addr_t)&tf->tf_sp, sizeof(tf->tf_sp), FALSE);
+	o7 = db_get_value((db_addr_t)&tf->tf_out[7], sizeof(tf->tf_out[7]),
+	    FALSE);
+	pc = db_get_value((db_addr_t)&tf->tf_tpc, sizeof(tf->tf_tpc), FALSE);
+	db_printf("user trace: trap %%o7=%#lx\n", o7);
+	while (count-- && sp != 0 && !db_pager_quit) {
+		db_printf("pc %#lx, sp %#lx\n", pc, sp);
+		/* First, check whether the frame is in the pcb. */
+		found = 0;
+		for (i = 0; i < pcb->pcb_nsaved; i++) {
+			if (pcb->pcb_rwsp[i] == sp) {
+				found = 1;
+				sp = pcb->pcb_rw[i].rw_in[6];
+				pc = pcb->pcb_rw[i].rw_in[7];
+				break;
+			}
+		}
+		if (!found) {
+			rsp = sp + SPOFF;
+			sp = 0;
+			if (copyin((void *)(rsp + offsetof(struct frame, fr_fp)),
+			    &sp, sizeof(sp)) != 0 ||
+			    copyin((void *)(rsp + offsetof(struct frame, fr_pc)),
+			    &pc, sizeof(pc)) != 0)
+				break;
+		}
+	}
+	db_printf("done\n");
+}
+
+static int
+db_print_trap(struct thread *td, struct trapframe *tf, int count)
+{
+	struct proc *p;
+	const char *symname;
+	c_db_sym_t sym;
+	db_expr_t diff;
+	db_addr_t func;
+	db_addr_t tpc;
+	u_long type;
+	u_long sfar;
+	u_long sfsr;
+	u_long tar;
+	u_long level;
+	u_long pil;
+	u_long code;
+	u_long o7;
+	int user;
+
+	p = td->td_proc;
+	type = db_get_value((db_addr_t)&tf->tf_type,
+	    sizeof(tf->tf_type), FALSE);
+	db_printf("-- %s", trap_msg[type & ~T_KERNEL]);
+	switch (type & ~T_KERNEL) {
+	case T_DATA_PROTECTION:
+		tar = (u_long)db_get_value((db_addr_t)&tf->tf_tar,
+		    sizeof(tf->tf_tar), FALSE);
+		db_printf(" tar=%#lx", tar);
+		/* fall through */
+	case T_DATA_EXCEPTION:
+	case T_INSTRUCTION_EXCEPTION:
+	case T_MEM_ADDRESS_NOT_ALIGNED:
+		sfar = (u_long)db_get_value((db_addr_t)&tf->tf_sfar,
+		    sizeof(tf->tf_sfar), FALSE);
+		sfsr = (u_long)db_get_value((db_addr_t)&tf->tf_sfsr,
+		    sizeof(tf->tf_sfsr), FALSE);
+		db_printf(" sfar=%#lx sfsr=%#lx", sfar, sfsr);
+		break;
+	case T_DATA_MISS:
+	case T_INSTRUCTION_MISS:
+		tar = (u_long)db_get_value((db_addr_t)&tf->tf_tar,
+		    sizeof(tf->tf_tar), FALSE);
+		db_printf(" tar=%#lx", tar);
+		break;
+	case T_SYSCALL:
+		code = db_get_value((db_addr_t)&tf->tf_global[1],
+		    sizeof(tf->tf_global[1]), FALSE);
+		db_printf(" (%ld", code);
+		if (code >= 0 && code < p->p_sysent->sv_size) {
+			func = (db_addr_t)p->p_sysent->sv_table[code].sy_call;
+			sym = db_search_symbol(func, DB_STGY_ANY, &diff);
+			if (sym != DB_SYM_NULL && diff == 0) {
+				db_symbol_values(sym, &symname, NULL);
+				db_printf(", %s, %s", p->p_sysent->sv_name,
+				    symname);
+			}
+			db_printf(")");
+		}
+		break;
+	case T_INTERRUPT:
+		level = (u_long)db_get_value((db_addr_t)&tf->tf_level,
+		    sizeof(tf->tf_level), FALSE);
+		pil = (u_long)db_get_value((db_addr_t)&tf->tf_pil,
+		    sizeof(tf->tf_pil), FALSE);
+		db_printf(" level=%#lx pil=%#lx", level, pil);
+		break;
+	default:
+		break;
+	}
+	o7 = (u_long)db_get_value((db_addr_t)&tf->tf_out[7],
+	    sizeof(tf->tf_out[7]), FALSE);
+	db_printf(" %%o7=%#lx --\n", o7);
+	user = (type & T_KERNEL) == 0;
+	if (user) {
+		tpc = db_get_value((db_addr_t)&tf->tf_tpc,
+		    sizeof(tf->tf_tpc), FALSE);
+		db_printf("userland() at ");
+		db_printsym(tpc, DB_STGY_PROC);
+		db_printf("\n");
+		db_utrace(td, tf, count);
+	}
+	return (user);
+}
+
+static int
+db_backtrace(struct thread *td, struct frame *fp, int count)
+{
+	struct trapframe *tf;
+	const char *name;
+	c_db_sym_t sym;
+	db_expr_t offset;
+	db_expr_t value;
+	db_addr_t npc;
+	db_addr_t pc;
+	int trap;
+	int user;
+
+	if (count == -1)
+		count = 1024;
+
+	trap = 0;
+	user = 0;
+	npc = 0;
+	while (count-- && !user && !db_pager_quit) {
+		pc = (db_addr_t)db_get_value((db_addr_t)&fp->fr_pc,
+		    sizeof(fp->fr_pc), FALSE);
+		if (trap) {
+			pc = npc;
+			trap = 0;
+		}
+		if (!INKERNEL((vm_offset_t)pc))
+			break;
+		sym = db_search_symbol(pc, DB_STGY_ANY, &offset);
+		if (sym == C_DB_SYM_NULL) {
+			value = 0;
+			name = NULL;
+		} else
+			db_symbol_values(sym, &name, &value);
+		if (name == NULL)
+			name = "(null)";
+		fp = (struct frame *)(db_get_value((db_addr_t)&fp->fr_fp,
+		   sizeof(fp->fr_fp), FALSE) + SPOFF);
+		if ((value > (u_long)tl_trap_begin &&
+		    value < (u_long)tl_trap_end) ||
+		    (value > (u_long)tl_text_begin &&
+		    value < (u_long)tl_text_end)) {
+			tf = (struct trapframe *)(fp + 1);
+			npc = db_get_value((db_addr_t)&tf->tf_tpc,
+			    sizeof(tf->tf_tpc), FALSE);
+			user = db_print_trap(td, tf, count);
+			trap = 1;
+		} else {
+			db_printf("%s() at ", name);
+			db_printsym(pc, DB_STGY_PROC);
+			db_printf("\n");
+		}
+	}
+	return (0);
+}
+
+void
+db_trace_self(void)
+{
+
+	db_backtrace(curthread,
+	    (struct frame *)__builtin_frame_address(1), -1);
+}
+
+int
+db_trace_thread(struct thread *td, int count)
+{
+	struct pcb *ctx;
+
+	ctx = kdb_thr_ctx(td);
+	return (db_backtrace(td,
+	    (struct frame *)(ctx->pcb_sp + SPOFF), count));
+}


Property changes on: trunk/sys/sparc64/sparc64/db_trace.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/dump_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/dump_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/dump_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,227 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * Copyright (c) 2002 Thomas Moestl
+ * 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 ``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/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/dump_machdep.c 224682 2011-08-06 17:45:52Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/cons.h>
+#include <sys/kernel.h>
+#include <sys/kerneldump.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
+#include <machine/metadata.h>
+#include <machine/kerneldump.h>
+#include <machine/ofw_mem.h>
+#include <machine/tsb.h>
+#include <machine/tlb.h>
+
+CTASSERT(sizeof(struct kerneldumpheader) == DEV_BSIZE);
+
+static struct kerneldumpheader kdh;
+static off_t dumplo, dumppos;
+
+/* Handle buffered writes. */
+static char buffer[DEV_BSIZE];
+static vm_size_t fragsz;
+
+#define	MAXDUMPSZ	(MAXDUMPPGS << PAGE_SHIFT)
+
+static int
+buf_write(struct dumperinfo *di, char *ptr, size_t sz)
+{
+	size_t len;
+	int error;
+
+	while (sz) {
+		len = DEV_BSIZE - fragsz;
+		if (len > sz)
+			len = sz;
+		bcopy(ptr, buffer + fragsz, len);
+		fragsz += len;
+		ptr += len;
+		sz -= len;
+		if (fragsz == DEV_BSIZE) {
+			error = dump_write(di, buffer, 0, dumplo,
+			    DEV_BSIZE);
+			if (error)
+				return error;
+			dumplo += DEV_BSIZE;
+			fragsz = 0;
+		}
+	}
+
+	return (0);
+}
+
+static int
+buf_flush(struct dumperinfo *di)
+{
+	int error;
+
+	if (fragsz == 0)
+		return (0);
+
+	error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
+	dumplo += DEV_BSIZE;
+	fragsz = 0;
+	return (error);
+}
+
+static int
+reg_write(struct dumperinfo *di, vm_paddr_t pa, vm_size_t size)
+{
+	struct sparc64_dump_reg r;
+
+	r.dr_pa = pa;
+	r.dr_size = size;
+	r.dr_offs = dumppos;
+	dumppos += size;
+	return (buf_write(di, (char *)&r, sizeof(r)));
+}
+
+static int
+blk_dump(struct dumperinfo *di, vm_paddr_t pa, vm_size_t size)
+{
+	vm_size_t pos, rsz;
+	vm_offset_t va;
+	int c, counter, error, twiddle;
+
+	printf("  chunk at %#lx: %ld bytes ", (u_long)pa, (long)size);
+
+	va = 0L;
+	error = counter = twiddle = 0;
+	for (pos = 0; pos < size; pos += MAXDUMPSZ, counter++) {
+		if (counter % 128 == 0)
+			printf("%c\b", "|/-\\"[twiddle++ & 3]);
+		rsz = size - pos;
+		rsz = (rsz > MAXDUMPSZ) ? MAXDUMPSZ : rsz;
+		va = TLB_PHYS_TO_DIRECT(pa + pos);
+		error = dump_write(di, (void *)va, 0, dumplo, rsz);
+		if (error)
+			break;
+		dumplo += rsz;
+
+		/* Check for user abort. */
+		c = cncheckc();
+		if (c == 0x03)
+			return (ECANCELED);
+		if (c != -1)
+			printf("(CTRL-C to abort)  ");
+	}
+	printf("... %s\n", (error) ? "fail" : "ok");
+	return (error);
+}
+
+void
+dumpsys(struct dumperinfo *di)
+{
+	struct sparc64_dump_hdr hdr;
+	vm_size_t size, totsize, hdrsize;
+	int error, i, nreg;
+
+	/* Calculate dump size. */
+	size = 0;
+	nreg = sparc64_nmemreg;
+	for (i = 0; i < sparc64_nmemreg; i++)
+		size += sparc64_memreg[i].mr_size;
+	/* Account for the header size. */
+	hdrsize = roundup2(sizeof(hdr) + sizeof(struct sparc64_dump_reg) * nreg,
+	    DEV_BSIZE);
+	size += hdrsize;
+
+	totsize = size + 2 * sizeof(kdh);
+	if (totsize > di->mediasize) {
+		printf("Insufficient space on device (need %ld, have %ld), "
+		    "refusing to dump.\n", (long)totsize,
+		    (long)di->mediasize);
+		error = ENOSPC;
+		goto fail;
+	}
+
+	/* Determine dump offset on device. */
+	dumplo = di->mediaoffset + di->mediasize - totsize;
+
+	mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_SPARC64_VERSION, size,
+	    di->blocksize);
+
+	printf("Dumping %lu MB (%d chunks)\n", (u_long)(size >> 20), nreg);
+
+	/* Dump leader */
+	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+	if (error)
+		goto fail;
+	dumplo += sizeof(kdh);
+
+	/* Dump the private header. */
+	hdr.dh_hdr_size = hdrsize;
+	hdr.dh_tsb_pa = tsb_kernel_phys;
+	hdr.dh_tsb_size = tsb_kernel_size;
+	hdr.dh_tsb_mask = tsb_kernel_mask;
+	hdr.dh_nregions = nreg;
+
+	if (buf_write(di, (char *)&hdr, sizeof(hdr)) != 0)
+		goto fail;
+
+	dumppos = hdrsize;
+	/* Now, write out the region descriptors. */
+	for (i = 0; i < sparc64_nmemreg; i++) {
+		error = reg_write(di, sparc64_memreg[i].mr_start,
+		    sparc64_memreg[i].mr_size);
+		if (error != 0)
+			goto fail;
+	}
+	buf_flush(di);
+
+	/* Dump memory chunks. */
+	for (i = 0; i < sparc64_nmemreg; i++) {
+		error = blk_dump(di, sparc64_memreg[i].mr_start,
+		    sparc64_memreg[i].mr_size);
+		if (error != 0)
+			goto fail;
+	}
+
+	/* Dump trailer */
+	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+	if (error)
+		goto fail;
+
+	/* Signal completion, signoff and exit stage left. */
+	dump_write(di, NULL, 0, 0, 0);
+	printf("\nDump complete\n");
+	return;
+
+ fail:
+	/* XXX It should look more like VMS :-) */
+	printf("** DUMP FAILED (ERROR %d) **\n", error);
+}


Property changes on: trunk/sys/sparc64/sparc64/dump_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/eeprom.c
===================================================================
--- trunk/sys/sparc64/sparc64/eeprom.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/eeprom.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,190 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 1994 Gordon W. Ross
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1996 Paul Kranenburg
+ * Copyright (c) 1996
+ * 	The President and Fellows of Harvard College. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *	This product includes software developed by Harvard University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Paul Kranenburg.
+ *	This product includes software developed by Harvard University.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: @(#)clock.c	8.1 (Berkeley) 6/11/93
+ *	from: NetBSD: clock.c,v 1.41 2001/07/24 19:29:25 eeh Exp
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/eeprom.c 227848 2011-11-22 21:55:40Z marius $");
+
+/*
+ * clock (eeprom) attaches at EBus, FireHose or SBus
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/eventhandler.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+
+#include <dev/ofw/ofw_bus.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <machine/ver.h>
+
+#include <sys/rman.h>
+
+#include <dev/mk48txx/mk48txxvar.h>
+
+#include "clock_if.h"
+
+static devclass_t eeprom_devclass;
+
+static device_probe_t eeprom_probe;
+static device_attach_t eeprom_attach;
+
+static device_method_t eeprom_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		eeprom_probe),
+	DEVMETHOD(device_attach,	eeprom_attach),
+
+	/* clock interface */
+	DEVMETHOD(clock_gettime,	mk48txx_gettime),
+	DEVMETHOD(clock_settime,	mk48txx_settime),
+
+	DEVMETHOD_END
+};
+
+static driver_t eeprom_driver = {
+	"eeprom",
+	eeprom_methods,
+	sizeof(struct mk48txx_softc),
+};
+
+DRIVER_MODULE(eeprom, ebus, eeprom_driver, eeprom_devclass, 0, 0);
+DRIVER_MODULE(eeprom, fhc, eeprom_driver, eeprom_devclass, 0, 0);
+DRIVER_MODULE(eeprom, sbus, eeprom_driver, eeprom_devclass, 0, 0);
+
+static int
+eeprom_probe(device_t dev)
+{
+	const char *name;
+
+	name = ofw_bus_get_name(dev);
+	if (strcmp(name, "eeprom") == 0 ||
+	    strcmp(name, "FJSV,eeprom") == 0) {
+		device_set_desc(dev, "EEPROM/clock");
+		return (0);
+	}
+	return (ENXIO);
+}
+
+static int
+eeprom_attach(device_t dev)
+{
+	struct mk48txx_softc *sc;
+	struct timespec ts;
+	int error, rid;
+
+	sc = device_get_softc(dev);
+
+	mtx_init(&sc->sc_mtx, "eeprom_mtx", NULL, MTX_DEF);
+
+	rid = 0;
+	sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->sc_res == NULL) {
+		device_printf(dev, "cannot allocate resources\n");
+		error = ENXIO;
+		goto fail_mtx;
+	}
+
+	if ((sc->sc_model = ofw_bus_get_model(dev)) == NULL) {
+		device_printf(dev, "cannot determine model\n");
+		error = ENXIO;
+		goto fail_res;
+	}
+
+	/* Our TOD clock year 0 is 1968. */
+	sc->sc_year0 = 1968;
+	/* Use default register read/write functions. */
+	sc->sc_flag = 0;
+	/*
+	 * Generally, if the `eeprom' node has a `watchdog-enable' property
+	 * this indicates that the watchdog part of the MK48T59 is usable,
+	 * i.e. its RST pin is connected to the WDR input of the CPUs or
+	 * something. The `eeprom' nodes of E250, E450 and the clock board
+	 * variant in Exx00 have such properties. For E250 and E450 the
+	 * watchdog just works, for Exx00 the delivery of the reset signal
+	 * apparently has to be additionally enabled elsewhere...
+	 * The OFW environment variable `watchdog-reboot?' is ignored for
+	 * these watchdogs as they always trigger a system reset when they
+	 * time out and can't be made to issue a break to the boot monitor
+	 * instead.
+	 */
+	if (OF_getproplen(ofw_bus_get_node(dev), "watchdog-enable") != -1 &&
+	    (strcmp(sparc64_model, "SUNW,Ultra-250") == 0 ||
+	    strcmp(sparc64_model, "SUNW,Ultra-4") == 0))
+		sc->sc_flag |= MK48TXX_WDOG_REGISTER | MK48TXX_WDOG_ENABLE_WDS;
+	if ((error = mk48txx_attach(dev)) != 0) {
+		device_printf(dev, "cannot attach time of day clock\n");
+		goto fail_res;
+	}
+
+	if (bootverbose) {
+		if (mk48txx_gettime(dev, &ts) != 0)
+			device_printf(dev, "invalid time");
+		else
+			device_printf(dev, "current time: %ld.%09ld\n",
+			    (long)ts.tv_sec, ts.tv_nsec);
+	}
+
+	return (0);
+
+ fail_res:
+	bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->sc_res);
+ fail_mtx:
+	mtx_destroy(&sc->sc_mtx);
+
+	return (error);
+}


Property changes on: trunk/sys/sparc64/sparc64/eeprom.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/elf_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/elf_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/elf_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,428 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * Copyright (c) 2000 Eduardo Horvath.
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ *
+ *	from: NetBSD: mdreloc.c,v 1.42 2008/04/28 20:23:04 martin Exp
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/elf_machdep.c 294136 2016-01-16 07:56:49Z dchagin $");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/linker.h>
+#include <sys/proc.h>
+#include <sys/sysent.h>
+#include <sys/imgact_elf.h>
+#include <sys/syscall.h>
+#include <sys/signalvar.h>
+#include <sys/vnode.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <machine/elf.h>
+
+#include "linker_if.h"
+
+static struct sysentvec elf64_freebsd_sysvec = {
+	.sv_size	= SYS_MAXSYSCALL,
+	.sv_table	= sysent,
+	.sv_mask	= 0,
+	.sv_sigsize	= 0,
+	.sv_sigtbl	= NULL,
+	.sv_errsize	= 0,
+	.sv_errtbl	= NULL,
+	.sv_transtrap	= NULL,
+	.sv_fixup	= __elfN(freebsd_fixup),
+	.sv_sendsig	= sendsig,
+	.sv_sigcode	= NULL,
+	.sv_szsigcode	= NULL,
+	.sv_prepsyscall	= NULL,
+	.sv_name	= "FreeBSD ELF64",
+	.sv_coredump	= __elfN(coredump),
+	.sv_imgact_try	= NULL,
+	.sv_minsigstksz	= MINSIGSTKSZ,
+	.sv_pagesize	= PAGE_SIZE,
+	.sv_minuser	= VM_MIN_ADDRESS,
+	.sv_maxuser	= VM_MAXUSER_ADDRESS,
+	.sv_usrstack	= USRSTACK,
+	.sv_psstrings	= PS_STRINGS,
+	.sv_stackprot	= VM_PROT_READ | VM_PROT_WRITE,
+	.sv_copyout_strings = exec_copyout_strings,
+	.sv_setregs	= exec_setregs,
+	.sv_fixlimit	= NULL,
+	.sv_maxssiz	= NULL,
+	.sv_flags	= SV_ABI_FREEBSD | SV_LP64,
+	.sv_set_syscall_retval = cpu_set_syscall_retval,
+	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
+	.sv_syscallnames = syscallnames,
+	.sv_schedtail	= NULL,
+	.sv_thread_detach = NULL,
+	.sv_trap	= NULL,
+};
+
+static Elf64_Brandinfo freebsd_brand_info = {
+	.brand		= ELFOSABI_FREEBSD,
+	.machine	= EM_SPARCV9,
+	.compat_3_brand	= "FreeBSD",
+	.emul_path	= NULL,
+	.interp_path	= "/libexec/ld-elf.so.1",
+	.sysvec		= &elf64_freebsd_sysvec,
+	.interp_newpath	= NULL,
+	.brand_note	= &elf64_freebsd_brandnote,
+	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
+};
+
+SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_FIRST,
+    (sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_info);
+
+static Elf64_Brandinfo freebsd_brand_oinfo = {
+	.brand		= ELFOSABI_FREEBSD,
+	.machine	= EM_SPARCV9,
+	.compat_3_brand	= "FreeBSD",
+	.emul_path	= NULL,
+	.interp_path	= "/usr/libexec/ld-elf.so.1",
+	.sysvec		= &elf64_freebsd_sysvec,
+	.interp_newpath	= NULL,
+	.brand_note	= &elf64_freebsd_brandnote,
+	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
+};
+
+SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
+    (sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_oinfo);
+
+void
+elf64_dump_thread(struct thread *td __unused, void *dst __unused,
+    size_t *off __unused)
+{
+
+}
+
+/*
+ * The following table holds for each relocation type:
+ *	- the width in bits of the memory location the relocation
+ *	  applies to (not currently used)
+ *	- the number of bits the relocation value must be shifted to the
+ *	  right (i.e. discard least significant bits) to fit into
+ *	  the appropriate field in the instruction word.
+ *	- flags indicating whether
+ *		* the relocation involves a symbol
+ *		* the relocation is relative to the current position
+ *		* the relocation is for a GOT entry
+ *		* the relocation is relative to the load address
+ *
+ */
+#define	_RF_S		0x80000000		/* Resolve symbol */
+#define	_RF_A		0x40000000		/* Use addend */
+#define	_RF_P		0x20000000		/* Location relative */
+#define	_RF_G		0x10000000		/* GOT offset */
+#define	_RF_B		0x08000000		/* Load address relative */
+#define	_RF_U		0x04000000		/* Unaligned */
+#define	_RF_X		0x02000000		/* Bare symbols, needs proc */
+#define	_RF_D		0x01000000		/* Use dynamic TLS offset */
+#define	_RF_O		0x00800000		/* Use static TLS offset */
+#define	_RF_I		0x00400000		/* Use TLS object ID */
+#define	_RF_SZ(s)	(((s) & 0xff) << 8)	/* memory target size */
+#define	_RF_RS(s)	( (s) & 0xff)		/* right shift */
+static const int reloc_target_flags[] = {
+	0,							/* NONE */
+	_RF_S|_RF_A|		_RF_SZ(8)  | _RF_RS(0),		/* 8 */
+	_RF_S|_RF_A|		_RF_SZ(16) | _RF_RS(0),		/* 16 */
+	_RF_S|_RF_A|		_RF_SZ(32) | _RF_RS(0),		/* 32 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(8)  | _RF_RS(0),		/* DISP_8 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(16) | _RF_RS(0),		/* DISP_16 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(0),		/* DISP_32 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(2),		/* WDISP_30 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(2),		/* WDISP_22 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(10),	/* HI22 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(0),		/* 22 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(0),		/* 13 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(0),		/* LO10 */
+	_RF_G|			_RF_SZ(32) | _RF_RS(0),		/* GOT10 */
+	_RF_G|			_RF_SZ(32) | _RF_RS(0),		/* GOT13 */
+	_RF_G|			_RF_SZ(32) | _RF_RS(10),	/* GOT22 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(0),		/* PC10 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(10),	/* PC22 */
+	      _RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(2),		/* WPLT30 */
+				_RF_SZ(32) | _RF_RS(0),		/* COPY */
+	_RF_S|_RF_A|		_RF_SZ(64) | _RF_RS(0),		/* GLOB_DAT */
+				_RF_SZ(32) | _RF_RS(0),		/* JMP_SLOT */
+	      _RF_A|	_RF_B|	_RF_SZ(64) | _RF_RS(0),		/* RELATIVE */
+	_RF_S|_RF_A|	_RF_U|	_RF_SZ(32) | _RF_RS(0),		/* UA_32 */
+
+	      _RF_A|		_RF_SZ(32) | _RF_RS(0),		/* PLT32 */
+	      _RF_A|		_RF_SZ(32) | _RF_RS(10),	/* HIPLT22 */
+	      _RF_A|		_RF_SZ(32) | _RF_RS(0),		/* LOPLT10 */
+	      _RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(0),		/* PCPLT32 */
+	      _RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(10),	/* PCPLT22 */
+	      _RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(0),		/* PCPLT10 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(0),		/* 10 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(0),		/* 11 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(64) | _RF_RS(0),		/* 64 */
+	_RF_S|_RF_A|/*extra*/	_RF_SZ(32) | _RF_RS(0),		/* OLO10 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(42),	/* HH22 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(32),	/* HM10 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(10),	/* LM22 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(42),	/* PC_HH22 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(32),	/* PC_HM10 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(10),	/* PC_LM22 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(2),		/* WDISP16 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(2),		/* WDISP19 */
+	_RF_S|_RF_A|		_RF_SZ(32) | _RF_RS(0),		/* GLOB_JMP */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(0),		/* 7 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(0),		/* 5 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(0),		/* 6 */
+	_RF_S|_RF_A|_RF_P|	_RF_SZ(64) | _RF_RS(0),		/* DISP64 */
+	      _RF_A|		_RF_SZ(64) | _RF_RS(0),		/* PLT64 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(10),	/* HIX22 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(0),		/* LOX10 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(22),	/* H44 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(12),	/* M44 */
+	_RF_S|_RF_A|_RF_X|	_RF_SZ(32) | _RF_RS(0),		/* L44 */
+	_RF_S|_RF_A|		_RF_SZ(64) | _RF_RS(0),		/* REGISTER */
+	_RF_S|_RF_A|	_RF_U|	_RF_SZ(64) | _RF_RS(0),		/* UA64 */
+	_RF_S|_RF_A|	_RF_U|	_RF_SZ(16) | _RF_RS(0),		/* UA16 */
+
+#if 0
+	/* TLS */
+	_RF_S|_RF_A|		_RF_SZ(32) | _RF_RS(10),	/* GD_HI22 */
+	_RF_S|_RF_A|		_RF_SZ(32) | _RF_RS(0),		/* GD_LO10 */
+	0,							/* GD_ADD */
+	      _RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(2),		/* GD_CALL */
+	_RF_S|_RF_A|		_RF_SZ(32) | _RF_RS(10),	/* LDM_HI22 */
+	_RF_S|_RF_A|		_RF_SZ(32) | _RF_RS(0),		/* LDM_LO10 */
+	0,							/* LDM_ADD */
+	      _RF_A|_RF_P|	_RF_SZ(32) | _RF_RS(2),		/* LDM_CALL */
+	_RF_S|_RF_A|		_RF_SZ(32) | _RF_RS(10),	/* LDO_HIX22 */
+	_RF_S|_RF_A|		_RF_SZ(32) | _RF_RS(0),		/* LDO_LOX10 */
+	0,							/* LDO_ADD */
+	_RF_S|_RF_A|		_RF_SZ(32) | _RF_RS(10),	/* IE_HI22 */
+	_RF_S|_RF_A|		_RF_SZ(32) | _RF_RS(0),		/* IE_LO10 */
+	0,							/* IE_LD */
+	0,							/* IE_LDX */
+	0,							/* IE_ADD */
+	_RF_S|_RF_A|	_RF_O|	_RF_SZ(32) | _RF_RS(10),	/* LE_HIX22 */
+	_RF_S|_RF_A|	_RF_O|	_RF_SZ(32) | _RF_RS(0),		/* LE_LOX10 */
+	_RF_S|		_RF_I|	_RF_SZ(32) | _RF_RS(0),		/* DTPMOD32 */
+	_RF_S|		_RF_I|	_RF_SZ(64) | _RF_RS(0),		/* DTPMOD64 */
+	_RF_S|_RF_A|	_RF_D|	_RF_SZ(32) | _RF_RS(0),		/* DTPOFF32 */
+	_RF_S|_RF_A|	_RF_D|	_RF_SZ(64) | _RF_RS(0),		/* DTPOFF64 */
+	_RF_S|_RF_A|	_RF_O|	_RF_SZ(32) | _RF_RS(0),		/* TPOFF32 */
+	_RF_S|_RF_A|	_RF_O|	_RF_SZ(64) | _RF_RS(0)		/* TPOFF64 */
+#endif
+};
+
+#if 0
+static const char *const reloc_names[] = {
+	"NONE", "8", "16", "32", "DISP_8", "DISP_16", "DISP_32", "WDISP_30",
+	"WDISP_22", "HI22", "22", "13", "LO10", "GOT10", "GOT13", "GOT22",
+	"PC10", "PC22", "WPLT30", "COPY", "GLOB_DAT", "JMP_SLOT", "RELATIVE",
+	"UA_32", "PLT32", "HIPLT22", "LOPLT10", "LOPLT10", "PCPLT22",
+	"PCPLT32", "10", "11", "64", "OLO10", "HH22", "HM10", "LM22",
+	"PC_HH22", "PC_HM10", "PC_LM22", "WDISP16", "WDISP19", "GLOB_JMP",
+	"7", "5", "6", "DISP64", "PLT64", "HIX22", "LOX10", "H44", "M44",
+	"L44", "REGISTER", "UA64", "UA16", "GD_HI22", "GD_LO10", "GD_ADD",
+	"GD_CALL", "LDM_HI22", "LDMO10", "LDM_ADD", "LDM_CALL", "LDO_HIX22",
+	"LDO_LOX10", "LDO_ADD", "IE_HI22", "IE_LO10", "IE_LD", "IE_LDX",
+	"IE_ADD", "LE_HIX22", "LE_LOX10", "DTPMOD32", "DTPMOD64", "DTPOFF32",
+	"DTPOFF64", "TPOFF32", "TPOFF64"
+};
+#endif
+
+#define	RELOC_RESOLVE_SYMBOL(t)		((reloc_target_flags[t] & _RF_S) != 0)
+#define	RELOC_PC_RELATIVE(t)		((reloc_target_flags[t] & _RF_P) != 0)
+#define	RELOC_BASE_RELATIVE(t)		((reloc_target_flags[t] & _RF_B) != 0)
+#define	RELOC_UNALIGNED(t)		((reloc_target_flags[t] & _RF_U) != 0)
+#define	RELOC_USE_ADDEND(t)		((reloc_target_flags[t] & _RF_A) != 0)
+#define	RELOC_BARE_SYMBOL(t)		((reloc_target_flags[t] & _RF_X) != 0)
+#define	RELOC_USE_TLS_DOFF(t)		((reloc_target_flags[t] & _RF_D) != 0)
+#define	RELOC_USE_TLS_OFF(t)		((reloc_target_flags[t] & _RF_O) != 0)
+#define	RELOC_USE_TLS_ID(t)		((reloc_target_flags[t] & _RF_I) != 0)
+#define	RELOC_TARGET_SIZE(t)		((reloc_target_flags[t] >> 8) & 0xff)
+#define	RELOC_VALUE_RIGHTSHIFT(t)	(reloc_target_flags[t] & 0xff)
+
+static const long reloc_target_bitmask[] = {
+#define	_BM(x)	(~(-(1ULL << (x))))
+	0,				/* NONE */
+	_BM(8), _BM(16), _BM(32),	/* 8, 16, 32 */
+	_BM(8), _BM(16), _BM(32),	/* DISP8, DISP16, DISP32 */
+	_BM(30), _BM(22),		/* WDISP30, WDISP22 */
+	_BM(22), _BM(22),		/* HI22, 22 */
+	_BM(13), _BM(10),		/* 13, LO10 */
+	_BM(10), _BM(13), _BM(22),	/* GOT10, GOT13, GOT22 */
+	_BM(10), _BM(22),		/* PC10, PC22 */
+	_BM(30), 0,			/* WPLT30, COPY */
+	_BM(32), _BM(32), _BM(32),	/* GLOB_DAT, JMP_SLOT, RELATIVE */
+	_BM(32), _BM(32),		/* UA32, PLT32 */
+	_BM(22), _BM(10),		/* HIPLT22, LOPLT10 */
+	_BM(32), _BM(22), _BM(10),	/* PCPLT32, PCPLT22, PCPLT10 */
+	_BM(10), _BM(11), -1,		/* 10, 11, 64 */
+	_BM(13), _BM(22),		/* OLO10, HH22 */
+	_BM(10), _BM(22),		/* HM10, LM22 */
+	_BM(22), _BM(10), _BM(22),	/* PC_HH22, PC_HM10, PC_LM22 */
+	_BM(16), _BM(19),		/* WDISP16, WDISP19 */
+	-1,				/* GLOB_JMP */
+	_BM(7), _BM(5), _BM(6),		/* 7, 5, 6 */
+	-1, -1,				/* DISP64, PLT64 */
+	_BM(22), _BM(13),		/* HIX22, LOX10 */
+	_BM(22), _BM(10), _BM(13),	/* H44, M44, L44 */
+	-1, -1, _BM(16),		/* REGISTER, UA64, UA16 */
+#if 0
+	_BM(22), _BM(10), 0, _BM(30),	/* GD_HI22, GD_LO10, GD_ADD, GD_CALL */
+	_BM(22), _BM(10), 0,		/* LDM_HI22, LDMO10, LDM_ADD */
+	_BM(30),			/* LDM_CALL */
+	_BM(22), _BM(10), 0,		/* LDO_HIX22, LDO_LOX10, LDO_ADD */
+	_BM(22), _BM(10), 0, 0,		/* IE_HI22, IE_LO10, IE_LD, IE_LDX */
+	0,				/* IE_ADD */
+	_BM(22), _BM(13),		/* LE_HIX22, LE_LOX10 */
+	_BM(32), -1,			/* DTPMOD32, DTPMOD64 */
+	_BM(32), -1,			/* DTPOFF32, DTPOFF64 */
+	_BM(32), -1			/* TPOFF32, TPOFF64 */
+#endif
+#undef _BM
+};
+#define	RELOC_VALUE_BITMASK(t)	(reloc_target_bitmask[t])
+
+int
+elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
+    int type, elf_lookup_fn lookup __unused)
+{
+	const Elf_Rela *rela;
+	Elf_Addr *where;
+
+	if (type != ELF_RELOC_RELA)
+		return (-1);
+
+	rela = (const Elf_Rela *)data;
+	if (ELF64_R_TYPE_ID(rela->r_info) != R_SPARC_RELATIVE)
+		return (-1);
+
+	where = (Elf_Addr *)(relocbase + rela->r_offset);
+	*where = elf_relocaddr(lf, rela->r_addend + relocbase);
+
+	return (0);
+}
+
+/* Process one elf relocation with addend. */
+int
+elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
+    elf_lookup_fn lookup)
+{
+	const Elf_Rela *rela;
+	Elf_Word *where32;
+	Elf_Addr *where;
+	Elf_Size rtype, symidx;
+	Elf_Addr value;
+	Elf_Addr mask;
+	Elf_Addr addr;
+	int error;
+
+	if (type != ELF_RELOC_RELA)
+		return (-1);
+
+	rela = (const Elf_Rela *)data;
+	where = (Elf_Addr *)(relocbase + rela->r_offset);
+	where32 = (Elf_Word *)where;
+	rtype = ELF64_R_TYPE_ID(rela->r_info);
+	symidx = ELF_R_SYM(rela->r_info);
+
+	if (rtype == R_SPARC_NONE || rtype == R_SPARC_RELATIVE)
+		return (0);
+
+	if (rtype == R_SPARC_JMP_SLOT || rtype == R_SPARC_COPY ||
+	    rtype >= sizeof(reloc_target_bitmask) /
+	    sizeof(*reloc_target_bitmask)) {
+		printf("kldload: unexpected relocation type %ld\n", rtype);
+		return (-1);
+	}
+
+	if (RELOC_UNALIGNED(rtype)) {
+		printf("kldload: unaligned relocation type %ld\n", rtype);
+		return (-1);
+	}
+
+	value = rela->r_addend;
+
+	if (RELOC_RESOLVE_SYMBOL(rtype)) {
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
+			return (-1);
+		value += addr;
+		if (RELOC_BARE_SYMBOL(rtype))
+			value = elf_relocaddr(lf, value);
+	}
+
+	if (rtype == R_SPARC_OLO10)
+		value = (value & 0x3ff) + ELF64_R_TYPE_DATA(rela->r_info);
+
+	if (rtype == R_SPARC_HIX22)
+		value ^= 0xffffffffffffffff;
+
+	if (RELOC_PC_RELATIVE(rtype))
+		value -= (Elf_Addr)where;
+
+	if (RELOC_BASE_RELATIVE(rtype))
+		value = elf_relocaddr(lf, value + relocbase);
+
+	mask = RELOC_VALUE_BITMASK(rtype);
+	value >>= RELOC_VALUE_RIGHTSHIFT(rtype);
+	value &= mask;
+
+	if (rtype == R_SPARC_LOX10)
+		value |= 0x1c00;
+
+	if (RELOC_TARGET_SIZE(rtype) > 32) {
+		*where &= ~mask;
+		*where |= value;
+	} else {
+		*where32 &= ~mask;
+		*where32 |= value;
+	}
+
+	return (0);
+}
+
+int
+elf_cpu_load_file(linker_file_t lf __unused)
+{
+
+	return (0);
+}
+
+int
+elf_cpu_unload_file(linker_file_t lf __unused)
+{
+
+	return (0);
+}


Property changes on: trunk/sys/sparc64/sparc64/elf_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/exception.S
===================================================================
--- trunk/sys/sparc64/sparc64/exception.S	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/exception.S	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,3069 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1997 Berkeley Software Design, Inc. 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. Berkeley Software Design Inc's name may not be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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.
+ *
+ *	BSDI $Id: locore.s,v 1.36.2.15 1999/08/23 22:34:41 cp Exp $
+ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/exception.S 293853 2016-01-13 21:38:52Z marius $");
+
+#include "opt_compat.h"
+#include "opt_ddb.h"
+
+#include <machine/asi.h>
+#include <machine/asmacros.h>
+#include <machine/frame.h>
+#include <machine/fsr.h>
+#include <machine/intr_machdep.h>
+#include <machine/ktr.h>
+#include <machine/pcb.h>
+#include <machine/pstate.h>
+#include <machine/trap.h>
+#include <machine/tsb.h>
+#include <machine/tstate.h>
+#include <machine/utrap.h>
+#include <machine/wstate.h>
+
+#include "assym.s"
+
+#define	TSB_ASI			0x0
+#define	TSB_KERNEL		0x0
+#define	TSB_KERNEL_MASK		0x0
+#define	TSB_KERNEL_PHYS		0x0
+#define	TSB_KERNEL_PHYS_END	0x0
+#define	TSB_QUAD_LDD		0x0
+
+	.register %g2,#ignore
+	.register %g3,#ignore
+	.register %g6,#ignore
+	.register %g7,#ignore
+
+/*
+ * Atomically set a bit in a TTE.
+ */
+#define	TTE_SET_BIT(r1, r2, r3, bit, a, asi) \
+	add	r1, TTE_DATA, r1 ; \
+	LD(x, a) [r1] asi, r2 ; \
+9:	or	r2, bit, r3 ; \
+	CAS(x, a) [r1] asi, r2, r3 ; \
+	cmp	r2, r3 ; \
+	bne,pn	%xcc, 9b ; \
+	 mov	r3, r2
+
+#define	TTE_SET_REF(r1, r2, r3, a, asi)	TTE_SET_BIT(r1, r2, r3, TD_REF, a, asi)
+#define	TTE_SET_W(r1, r2, r3, a, asi)	TTE_SET_BIT(r1, r2, r3, TD_W, a, asi)
+
+/*
+ * Macros for spilling and filling live windows.
+ *
+ * NOTE: These macros use exactly 16 instructions, and it is assumed that the
+ * handler will not use more than 24 instructions total, to leave room for
+ * resume vectors which occupy the last 8 instructions.
+ */
+
+#define	SPILL(storer, base, size, asi) \
+	storer	%l0, [base + (0 * size)] asi ; \
+	storer	%l1, [base + (1 * size)] asi ; \
+	storer	%l2, [base + (2 * size)] asi ; \
+	storer	%l3, [base + (3 * size)] asi ; \
+	storer	%l4, [base + (4 * size)] asi ; \
+	storer	%l5, [base + (5 * size)] asi ; \
+	storer	%l6, [base + (6 * size)] asi ; \
+	storer	%l7, [base + (7 * size)] asi ; \
+	storer	%i0, [base + (8 * size)] asi ; \
+	storer	%i1, [base + (9 * size)] asi ; \
+	storer	%i2, [base + (10 * size)] asi ; \
+	storer	%i3, [base + (11 * size)] asi ; \
+	storer	%i4, [base + (12 * size)] asi ; \
+	storer	%i5, [base + (13 * size)] asi ; \
+	storer	%i6, [base + (14 * size)] asi ; \
+	storer	%i7, [base + (15 * size)] asi
+
+#define	FILL(loader, base, size, asi) \
+	loader	[base + (0 * size)] asi, %l0 ; \
+	loader	[base + (1 * size)] asi, %l1 ; \
+	loader	[base + (2 * size)] asi, %l2 ; \
+	loader	[base + (3 * size)] asi, %l3 ; \
+	loader	[base + (4 * size)] asi, %l4 ; \
+	loader	[base + (5 * size)] asi, %l5 ; \
+	loader	[base + (6 * size)] asi, %l6 ; \
+	loader	[base + (7 * size)] asi, %l7 ; \
+	loader	[base + (8 * size)] asi, %i0 ; \
+	loader	[base + (9 * size)] asi, %i1 ; \
+	loader	[base + (10 * size)] asi, %i2 ; \
+	loader	[base + (11 * size)] asi, %i3 ; \
+	loader	[base + (12 * size)] asi, %i4 ; \
+	loader	[base + (13 * size)] asi, %i5 ; \
+	loader	[base + (14 * size)] asi, %i6 ; \
+	loader	[base + (15 * size)] asi, %i7
+
+#define	ERRATUM50(reg)	mov reg, reg
+
+#define	KSTACK_SLOP	1024
+
+/*
+ * Sanity check the kernel stack and bail out if it's wrong.
+ * XXX: doesn't handle being on the panic stack.
+ */
+#define	KSTACK_CHECK \
+	dec	16, ASP_REG ; \
+	stx	%g1, [ASP_REG + 0] ; \
+	stx	%g2, [ASP_REG + 8] ; \
+	add	%sp, SPOFF, %g1 ; \
+	andcc	%g1, (1 << PTR_SHIFT) - 1, %g0 ; \
+	bnz,a	%xcc, tl1_kstack_fault ; \
+	 inc	16, ASP_REG ; \
+	ldx	[PCPU(CURTHREAD)], %g2 ; \
+	ldx	[%g2 + TD_KSTACK], %g2 ; \
+	add	%g2, KSTACK_SLOP, %g2 ; \
+	subcc	%g1, %g2, %g1 ; \
+	ble,a	%xcc, tl1_kstack_fault ; \
+	 inc	16, ASP_REG ; \
+	set	KSTACK_PAGES * PAGE_SIZE, %g2 ; \
+	cmp	%g1, %g2 ; \
+	bgt,a	%xcc, tl1_kstack_fault ; \
+	 inc	16, ASP_REG ; \
+	ldx	[ASP_REG + 8], %g2 ; \
+	ldx	[ASP_REG + 0], %g1 ; \
+	inc	16, ASP_REG
+
+	.globl	tl_text_begin
+tl_text_begin:
+	nop
+
+ENTRY(tl1_kstack_fault)
+	rdpr	%tl, %g1
+1:	cmp	%g1, 2
+	be,a	2f
+	 nop
+
+#if KTR_COMPILE & KTR_TRAP
+	CATR(KTR_TRAP, "tl1_kstack_fault: tl=%#lx tpc=%#lx tnpc=%#lx"
+	    , %g2, %g3, %g4, 7, 8, 9)
+	rdpr	%tl, %g3
+	stx	%g3, [%g2 + KTR_PARM1]
+	rdpr	%tpc, %g3
+	stx	%g3, [%g2 + KTR_PARM1]
+	rdpr	%tnpc, %g3
+	stx	%g3, [%g2 + KTR_PARM1]
+9:
+#endif
+
+	sub	%g1, 1, %g1
+	wrpr	%g1, 0, %tl
+	ba,a	%xcc, 1b
+	 nop
+
+2:
+#if KTR_COMPILE & KTR_TRAP
+	CATR(KTR_TRAP,
+	    "tl1_kstack_fault: sp=%#lx ks=%#lx cr=%#lx cs=%#lx ow=%#lx ws=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	add	%sp, SPOFF, %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	ldx	[PCPU(CURTHREAD)], %g2
+	ldx	[%g2 + TD_KSTACK], %g2
+	stx	%g2, [%g1 + KTR_PARM2]
+	rdpr	%canrestore, %g2
+	stx	%g2, [%g1 + KTR_PARM3]
+	rdpr	%cansave, %g2
+	stx	%g2, [%g1 + KTR_PARM4]
+	rdpr	%otherwin, %g2
+	stx	%g2, [%g1 + KTR_PARM5]
+	rdpr	%wstate, %g2
+	stx	%g2, [%g1 + KTR_PARM6]
+9:
+#endif
+
+	wrpr	%g0, 0, %canrestore
+	wrpr	%g0, 6, %cansave
+	wrpr	%g0, 0, %otherwin
+	wrpr	%g0, WSTATE_KERNEL, %wstate
+
+	sub	ASP_REG, SPOFF + CCFSZ, %sp
+	clr	%fp
+
+	set	trap, %o2
+	ba	%xcc, tl1_trap
+	 mov	T_KSTACK_FAULT | T_KERNEL, %o0
+END(tl1_kstack_fault)
+
+/*
+ * Magic to resume from a spill or fill trap.  If we get an alignment or an
+ * MMU fault during a spill or a fill, this macro will detect the fault and
+ * resume at a set instruction offset in the trap handler.
+ *
+ * To check if the previous trap was a spill/fill we convert the trapped pc
+ * to a trap type and verify that it is in the range of spill/fill vectors.
+ * The spill/fill vectors are types 0x80-0xff and 0x280-0x2ff, masking off the
+ * tl bit allows us to detect both ranges with one test.
+ *
+ * This is:
+ *	0x80 <= (((%tpc - %tba) >> 5) & ~0x200) < 0x100
+ *
+ * To calculate the new pc we take advantage of the xor feature of wrpr.
+ * Forcing all the low bits of the trapped pc on we can produce any offset
+ * into the spill/fill vector.  The size of a spill/fill trap vector is 0x80.
+ *
+ *	0x7f ^ 0x1f == 0x60
+ *	0x1f == (0x80 - 0x60) - 1
+ *
+ * Which are the offset and xor value used to resume from alignment faults.
+ */
+
+/*
+ * Determine if we have trapped inside of a spill/fill vector, and if so resume
+ * at a fixed instruction offset in the trap vector.  Must be called on
+ * alternate globals.
+ */
+#define	RESUME_SPILLFILL_MAGIC(stxa_g0_sfsr, xor) \
+	dec	16, ASP_REG ; \
+	stx	%g1, [ASP_REG + 0] ; \
+	stx	%g2, [ASP_REG + 8] ; \
+	rdpr	%tpc, %g1 ; \
+	ERRATUM50(%g1) ; \
+	rdpr	%tba, %g2 ; \
+	sub	%g1, %g2, %g2 ; \
+	srlx	%g2, 5, %g2 ; \
+	andn	%g2, 0x200, %g2 ; \
+	cmp	%g2, 0x80 ; \
+	blu,pt	%xcc, 9f ; \
+	 cmp	%g2, 0x100 ; \
+	bgeu,pt	%xcc, 9f ; \
+	 or	%g1, 0x7f, %g1 ; \
+	wrpr	%g1, xor, %tnpc ; \
+	stxa_g0_sfsr ; \
+	ldx	[ASP_REG + 8], %g2 ; \
+	ldx	[ASP_REG + 0], %g1 ; \
+	inc	16, ASP_REG ; \
+	done ; \
+9:	ldx	[ASP_REG + 8], %g2 ; \
+	ldx	[ASP_REG + 0], %g1 ; \
+	inc	16, ASP_REG
+
+/*
+ * For certain faults we need to clear the SFSR MMU register before returning.
+ */
+#define	RSF_CLR_SFSR \
+	wr	%g0, ASI_DMMU, %asi ; \
+	stxa	%g0, [%g0 + AA_DMMU_SFSR] %asi
+
+#define	RSF_XOR(off)	((0x80 - off) - 1)
+
+/*
+ * Instruction offsets in spill and fill trap handlers for handling certain
+ * nested traps, and corresponding xor constants for wrpr.
+ */
+#define	RSF_OFF_ALIGN	0x60
+#define	RSF_OFF_MMU	0x70
+
+#define	RESUME_SPILLFILL_ALIGN \
+	RESUME_SPILLFILL_MAGIC(RSF_CLR_SFSR, RSF_XOR(RSF_OFF_ALIGN))
+#define	RESUME_SPILLFILL_MMU \
+	RESUME_SPILLFILL_MAGIC(EMPTY, RSF_XOR(RSF_OFF_MMU))
+#define	RESUME_SPILLFILL_MMU_CLR_SFSR \
+	RESUME_SPILLFILL_MAGIC(RSF_CLR_SFSR, RSF_XOR(RSF_OFF_MMU))
+
+/*
+ * Constant to add to %tnpc when taking a fill trap just before returning to
+ * user mode.
+ */
+#define	RSF_FILL_INC	tl0_ret_fill_end - tl0_ret_fill
+
+/*
+ * Generate a T_SPILL or T_FILL trap if the window operation fails.
+ */
+#define	RSF_TRAP(type) \
+	ba	%xcc, tl0_sftrap ; \
+	 mov	type, %g2 ; \
+	.align	16
+
+/*
+ * Game over if the window operation fails.
+ */
+#define	RSF_FATAL(type) \
+	ba	%xcc, rsf_fatal ; \
+	 mov	type, %g2 ; \
+	.align	16
+
+/*
+ * Magic to resume from a failed fill a few instructions after the corrsponding
+ * restore.  This is used on return from the kernel to usermode.
+ */
+#define	RSF_FILL_MAGIC \
+	rdpr	%tnpc, %g1 ; \
+	add	%g1, RSF_FILL_INC, %g1 ; \
+	wrpr	%g1, 0, %tnpc ; \
+	done ; \
+	.align	16
+
+/*
+ * Spill to the pcb if a spill to the user stack in kernel mode fails.
+ */
+#define	RSF_SPILL_TOPCB \
+	ba,a	%xcc, tl1_spill_topcb ; \
+	 nop ; \
+	.align	16
+
+ENTRY(rsf_fatal)
+#if KTR_COMPILE & KTR_TRAP
+	CATR(KTR_TRAP, "rsf_fatal: bad window trap tt=%#lx type=%#lx"
+	    , %g1, %g3, %g4, 7, 8, 9)
+	rdpr	%tt, %g3
+	stx	%g3, [%g1 + KTR_PARM1]
+	stx	%g2, [%g1 + KTR_PARM2]
+9:
+#endif
+
+	KSTACK_CHECK
+
+	sir
+END(rsf_fatal)
+
+	.data
+	_ALIGN_DATA
+	.globl	intrnames, sintrnames
+intrnames:
+	.space	(IV_MAX + PIL_MAX) * (MAXCOMLEN + 1)
+sintrnames:
+	.quad	(IV_MAX + PIL_MAX) * (MAXCOMLEN + 1)
+
+	.globl	intrcnt, sintrcnt
+intrcnt:
+	.space	(IV_MAX + PIL_MAX) * 8
+sintrcnt:
+	.quad	(IV_MAX + PIL_MAX) * 8
+
+	.text
+
+/*
+ * Trap table and associated macros
+ *
+ * Due to its size a trap table is an inherently hard thing to represent in
+ * code in a clean way.  There are approximately 1024 vectors, of 8 or 32
+ * instructions each, many of which are identical.  The way that this is
+ * laid out is the instructions (8 or 32) for the actual trap vector appear
+ * as an AS macro.  In general this code branches to tl0_trap or tl1_trap,
+ * but if not supporting code can be placed just after the definition of the
+ * macro.  The macros are then instantiated in a different section (.trap),
+ * which is setup to be placed by the linker at the beginning of .text, and the
+ * code around the macros is moved to the end of trap table.  In this way the
+ * code that must be sequential in memory can be split up, and located near
+ * its supporting code so that it is easier to follow.
+ */
+
+	/*
+	 * Clean window traps occur when %cleanwin is zero to ensure that data
+	 * is not leaked between address spaces in registers.
+	 */
+	.macro	clean_window
+	clr	%o0
+	clr	%o1
+	clr	%o2
+	clr	%o3
+	clr	%o4
+	clr	%o5
+	clr	%o6
+	clr	%o7
+	clr	%l0
+	clr	%l1
+	clr	%l2
+	clr	%l3
+	clr	%l4
+	clr	%l5
+	clr	%l6
+	rdpr	%cleanwin, %l7
+	inc	%l7
+	wrpr	%l7, 0, %cleanwin
+	clr	%l7
+	retry
+	.align	128
+	.endm
+
+	/*
+	 * Stack fixups for entry from user mode.  We are still running on the
+	 * user stack, and with its live registers, so we must save soon.  We
+	 * are on alternate globals so we do have some registers.  Set the
+	 * transitional window state, and do the save.  If this traps we
+	 * attempt to spill a window to the user stack.  If this fails, we
+	 * spill the window to the pcb and continue.  Spilling to the pcb
+	 * must not fail.
+	 *
+	 * NOTE: Must be called with alternate globals and clobbers %g1.
+	 */
+
+	.macro	tl0_split
+	rdpr	%wstate, %g1
+	wrpr	%g1, WSTATE_TRANSITION, %wstate
+	save
+	.endm
+
+	.macro	tl0_setup	type
+	tl0_split
+	clr	%o1
+	set	trap, %o2
+	ba	%xcc, tl0_utrap
+	 mov	\type, %o0
+	.endm
+
+	/*
+	 * Generic trap type.  Call trap() with the specified type.
+	 */
+	.macro	tl0_gen		type
+	tl0_setup \type
+	.align	32
+	.endm
+
+	/*
+	 * This is used to suck up the massive swaths of reserved trap types.
+	 * Generates count "reserved" trap vectors.
+	 */
+	.macro	tl0_reserved	count
+	.rept	\count
+	tl0_gen	T_RESERVED
+	.endr
+	.endm
+
+	.macro	tl1_split
+	rdpr	%wstate, %g1
+	wrpr	%g1, WSTATE_NESTED, %wstate
+	save	%sp, -(CCFSZ + TF_SIZEOF), %sp
+	.endm
+
+	.macro	tl1_setup	type
+	tl1_split
+	clr	%o1
+	set	trap, %o2
+	ba	%xcc, tl1_trap
+	 mov	\type | T_KERNEL, %o0
+	.endm
+
+	.macro	tl1_gen		type
+	tl1_setup \type
+	.align	32
+	.endm
+
+	.macro	tl1_reserved	count
+	.rept	\count
+	tl1_gen	T_RESERVED
+	.endr
+	.endm
+
+	.macro	tl0_insn_excptn
+	wrpr	%g0, PSTATE_ALT, %pstate
+	wr	%g0, ASI_IMMU, %asi
+	rdpr	%tpc, %g3
+	ldxa	[%g0 + AA_IMMU_SFSR] %asi, %g4
+	/*
+	 * XXX in theory, a store to AA_IMMU_SFSR must be immediately
+	 * followed by a DONE, FLUSH or RETRY for USIII.  In practice,
+	 * this triggers a RED state exception though.
+	 */
+	stxa	%g0, [%g0 + AA_IMMU_SFSR] %asi
+	membar	#Sync
+	ba	%xcc, tl0_sfsr_trap
+	 mov	T_INSTRUCTION_EXCEPTION, %g2
+	.align	32
+	.endm
+
+	.macro	tl0_data_excptn
+	wrpr	%g0, PSTATE_ALT, %pstate
+	wr	%g0, ASI_DMMU, %asi
+	ldxa	[%g0 + AA_DMMU_SFAR] %asi, %g3
+	ldxa	[%g0 + AA_DMMU_SFSR] %asi, %g4
+	stxa	%g0, [%g0 + AA_DMMU_SFSR] %asi
+	membar	#Sync
+	ba	%xcc, tl0_sfsr_trap
+	 mov	T_DATA_EXCEPTION, %g2
+	.align	32
+	.endm
+
+	.macro	tl0_align
+	wr	%g0, ASI_DMMU, %asi
+	ldxa	[%g0 + AA_DMMU_SFAR] %asi, %g3
+	ldxa	[%g0 + AA_DMMU_SFSR] %asi, %g4
+	stxa	%g0, [%g0 + AA_DMMU_SFSR] %asi
+	membar	#Sync
+	ba	%xcc, tl0_sfsr_trap
+	 mov	T_MEM_ADDRESS_NOT_ALIGNED, %g2
+	.align	32
+	.endm
+
+ENTRY(tl0_sfsr_trap)
+	tl0_split
+	clr	%o1
+	set	trap, %o2
+	mov	%g3, %o4
+	mov	%g4, %o5
+	ba	%xcc, tl0_utrap
+	 mov	%g2, %o0
+END(tl0_sfsr_trap)
+
+	.macro	tl0_intr level, mask
+	tl0_split
+	set	\mask, %o1
+	ba	%xcc, tl0_intr
+	 mov	\level, %o0
+	.align	32
+	.endm
+
+#define	INTR(level, traplvl)						\
+	tl ## traplvl ## _intr	level, 1 << level
+
+#define	TICK(traplvl) \
+	tl ## traplvl ## _intr	PIL_TICK, 0x10001
+
+#define	INTR_LEVEL(tl)							\
+	INTR(1, tl) ;							\
+	INTR(2, tl) ;							\
+	INTR(3, tl) ;							\
+	INTR(4, tl) ;							\
+	INTR(5, tl) ;							\
+	INTR(6, tl) ;							\
+	INTR(7, tl) ;							\
+	INTR(8, tl) ;							\
+	INTR(9, tl) ;							\
+	INTR(10, tl) ;							\
+	INTR(11, tl) ;							\
+	INTR(12, tl) ;							\
+	INTR(13, tl) ;							\
+	TICK(tl) ;							\
+	INTR(15, tl) ;
+
+	.macro	tl0_intr_level
+	INTR_LEVEL(0)
+	.endm
+
+	.macro	intr_vector
+	ldxa	[%g0] ASI_INTR_RECEIVE, %g1
+	andcc	%g1, IRSR_BUSY, %g0
+	bnz,a,pt %xcc, intr_vector
+	 nop
+	ba,a,pt	%xcc, intr_vector_stray
+	 nop
+	.align	32
+	.endm
+
+	.macro	tl0_immu_miss
+	/*
+	 * Load the context and the virtual page number from the tag access
+	 * register.  We ignore the context.
+	 */
+	wr	%g0, ASI_IMMU, %asi
+	ldxa	[%g0 + AA_IMMU_TAR] %asi, %g1
+
+	/*
+	 * Initialize the page size walker.
+	 */
+	mov	TS_MIN, %g2
+
+	/*
+	 * Loop over all supported page sizes.
+	 */
+
+	/*
+	 * Compute the page shift for the page size we are currently looking
+	 * for.
+	 */
+1:	add	%g2, %g2, %g3
+	add	%g3, %g2, %g3
+	add	%g3, PAGE_SHIFT, %g3
+
+	/*
+	 * Extract the virtual page number from the contents of the tag
+	 * access register.
+	 */
+	srlx	%g1, %g3, %g3
+
+	/*
+	 * Compute the TTE bucket address.
+	 */
+	ldxa	[%g0 + AA_IMMU_TSB] %asi, %g5
+	and	%g3, TSB_BUCKET_MASK, %g4
+	sllx	%g4, TSB_BUCKET_SHIFT + TTE_SHIFT, %g4
+	add	%g4, %g5, %g4
+
+	/*
+	 * Compute the TTE tag target.
+	 */
+	sllx	%g3, TV_SIZE_BITS, %g3
+	or	%g3, %g2, %g3
+
+	/*
+	 * Loop over the TTEs in this bucket.
+	 */
+
+	/*
+	 * Load the TTE.  Note that this instruction may fault, clobbering
+	 * the contents of the tag access register, %g5, %g6, and %g7.  We
+	 * do not use %g5, and %g6 and %g7 are not used until this instruction
+	 * completes successfully.
+	 */
+2:	ldda	[%g4] ASI_NUCLEUS_QUAD_LDD, %g6 /*, %g7 */
+
+	/*
+	 * Check that it's valid and executable and that the TTE tags match.
+	 */
+	brgez,pn %g7, 3f
+	 andcc	%g7, TD_EXEC, %g0
+	bz,pn	%xcc, 3f
+	 cmp	%g3, %g6
+	bne,pn	%xcc, 3f
+	 EMPTY
+
+	/*
+	 * We matched a TTE, load the TLB.
+	 */
+
+	/*
+	 * Set the reference bit, if it's currently clear.
+	 */
+	 andcc	%g7, TD_REF, %g0
+	bz,a,pn	%xcc, tl0_immu_miss_set_ref
+	 nop
+
+	/*
+	 * Load the TTE tag and data into the TLB and retry the instruction.
+	 */
+	stxa	%g1, [%g0 + AA_IMMU_TAR] %asi
+	stxa	%g7, [%g0] ASI_ITLB_DATA_IN_REG
+	retry
+
+	/*
+	 * Advance to the next TTE in this bucket, and check the low bits
+	 * of the bucket pointer to see if we've finished the bucket.
+	 */
+3:	add	%g4, 1 << TTE_SHIFT, %g4
+	andcc	%g4, (1 << (TSB_BUCKET_SHIFT + TTE_SHIFT)) - 1, %g0
+	bnz,pt	%xcc, 2b
+	 EMPTY
+
+	/*
+	 * See if we just checked the largest page size, and advance to the
+	 * next one if not.
+	 */
+	 cmp	%g2, TS_MAX
+	bne,pt	%xcc, 1b
+	 add	%g2, 1, %g2
+
+	/*
+	 * Not in user TSB, call C code.
+	 */
+	ba,a	%xcc, tl0_immu_miss_trap
+	.align	128
+	.endm
+
+ENTRY(tl0_immu_miss_set_ref)
+	/*
+	 * Set the reference bit.
+	 */
+	TTE_SET_REF(%g4, %g2, %g3, a, ASI_N)
+
+	/*
+	 * May have become invalid during casxa, in which case start over.
+	 */
+	brgez,pn %g2, 1f
+	 nop
+
+	/*
+	 * Load the TTE tag and data into the TLB and retry the instruction.
+	 */
+	stxa	%g1, [%g0 + AA_IMMU_TAR] %asi
+	stxa	%g2, [%g0] ASI_ITLB_DATA_IN_REG
+1:	retry
+END(tl0_immu_miss_set_ref)
+
+ENTRY(tl0_immu_miss_trap)
+	/*
+	 * Put back the contents of the tag access register, in case we
+	 * faulted.
+	 */
+	sethi	%hi(KERNBASE), %g2
+	stxa	%g1, [%g0 + AA_IMMU_TAR] %asi
+	flush	%g2
+
+	/*
+	 * Switch to alternate globals.
+	 */
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	/*
+	 * Reload the tag access register.
+	 */
+	ldxa	[%g0 + AA_IMMU_TAR] %asi, %g2
+
+	/*
+	 * Save the tag access register, and call common trap code.
+	 */
+	tl0_split
+	clr	%o1
+	set	trap, %o2
+	mov	%g2, %o3
+	ba	%xcc, tl0_utrap
+	 mov	T_INSTRUCTION_MISS, %o0
+END(tl0_immu_miss_trap)
+
+	.macro	tl0_dmmu_miss
+	/*
+	 * Load the context and the virtual page number from the tag access
+	 * register.  We ignore the context.
+	 */
+	wr	%g0, ASI_DMMU, %asi
+	ldxa	[%g0 + AA_DMMU_TAR] %asi, %g1
+
+	/*
+	 * Initialize the page size walker.
+	 */
+tl1_dmmu_miss_user:
+	mov	TS_MIN, %g2
+
+	/*
+	 * Loop over all supported page sizes.
+	 */
+
+	/*
+	 * Compute the page shift for the page size we are currently looking
+	 * for.
+	 */
+1:	add	%g2, %g2, %g3
+	add	%g3, %g2, %g3
+	add	%g3, PAGE_SHIFT, %g3
+
+	/*
+	 * Extract the virtual page number from the contents of the tag
+	 * access register.
+	 */
+	srlx	%g1, %g3, %g3
+
+	/*
+	 * Compute the TTE bucket address.
+	 */
+	ldxa	[%g0 + AA_DMMU_TSB] %asi, %g5
+	and	%g3, TSB_BUCKET_MASK, %g4
+	sllx	%g4, TSB_BUCKET_SHIFT + TTE_SHIFT, %g4
+	add	%g4, %g5, %g4
+
+	/*
+	 * Compute the TTE tag target.
+	 */
+	sllx	%g3, TV_SIZE_BITS, %g3
+	or	%g3, %g2, %g3
+
+	/*
+	 * Loop over the TTEs in this bucket.
+	 */
+
+	/*
+	 * Load the TTE.  Note that this instruction may fault, clobbering
+	 * the contents of the tag access register, %g5, %g6, and %g7.  We
+	 * do not use %g5, and %g6 and %g7 are not used until this instruction
+	 * completes successfully.
+	 */
+2:	ldda	[%g4] ASI_NUCLEUS_QUAD_LDD, %g6 /*, %g7 */
+
+	/*
+	 * Check that it's valid and that the virtual page numbers match.
+	 */
+	brgez,pn %g7, 3f
+	 cmp	%g3, %g6
+	bne,pn	%xcc, 3f
+	 EMPTY
+
+	/*
+	 * We matched a TTE, load the TLB.
+	 */
+
+	/*
+	 * Set the reference bit, if it's currently clear.
+	 */
+	 andcc	%g7, TD_REF, %g0
+	bz,a,pn	%xcc, tl0_dmmu_miss_set_ref
+	 nop
+
+	/*
+	 * Load the TTE tag and data into the TLB and retry the instruction.
+	 */
+	stxa	%g1, [%g0 + AA_DMMU_TAR] %asi
+	stxa	%g7, [%g0] ASI_DTLB_DATA_IN_REG
+	retry
+
+	/*
+	 * Advance to the next TTE in this bucket, and check the low bits
+	 * of the bucket pointer to see if we've finished the bucket.
+	 */
+3:	add	%g4, 1 << TTE_SHIFT, %g4
+	andcc	%g4, (1 << (TSB_BUCKET_SHIFT + TTE_SHIFT)) - 1, %g0
+	bnz,pt	%xcc, 2b
+	 EMPTY
+
+	/*
+	 * See if we just checked the largest page size, and advance to the
+	 * next one if not.
+	 */
+	 cmp	%g2, TS_MAX
+	bne,pt	%xcc, 1b
+	 add	%g2, 1, %g2
+
+	/*
+	 * Not in user TSB, call C code.
+	 */
+	ba,a	%xcc, tl0_dmmu_miss_trap
+	.align	128
+	.endm
+
+ENTRY(tl0_dmmu_miss_set_ref)
+	/*
+	 * Set the reference bit.
+	 */
+	TTE_SET_REF(%g4, %g2, %g3, a, ASI_N)
+
+	/*
+	 * May have become invalid during casxa, in which case start over.
+	 */
+	brgez,pn %g2, 1f
+	 nop
+
+	/*
+	 * Load the TTE tag and data into the TLB and retry the instruction.
+	 */
+	stxa	%g1, [%g0 + AA_DMMU_TAR] %asi
+	stxa	%g2, [%g0] ASI_DTLB_DATA_IN_REG
+1:	retry
+END(tl0_dmmu_miss_set_ref)
+
+ENTRY(tl0_dmmu_miss_trap)
+	/*
+	 * Put back the contents of the tag access register, in case we
+	 * faulted.
+	 */
+	stxa	%g1, [%g0 + AA_DMMU_TAR] %asi
+	membar	#Sync
+
+	/*
+	 * Switch to alternate globals.
+	 */
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	/*
+	 * Check if we actually came from the kernel.
+	 */
+	rdpr	%tl, %g1
+	cmp	%g1, 1
+	bgt,a,pn %xcc, 1f
+	 nop
+
+	/*
+	 * Reload the tag access register.
+	 */
+	ldxa	[%g0 + AA_DMMU_TAR] %asi, %g2
+
+	/*
+	 * Save the tag access register and call common trap code.
+	 */
+	tl0_split
+	clr	%o1
+	set	trap, %o2
+	mov	%g2, %o3
+	ba	%xcc, tl0_utrap
+	 mov	T_DATA_MISS, %o0
+
+	/*
+	 * Handle faults during window spill/fill.
+	 */
+1:	RESUME_SPILLFILL_MMU
+
+	/*
+	 * Reload the tag access register.
+	 */
+	ldxa	[%g0 + AA_DMMU_TAR] %asi, %g2
+
+	tl1_split
+	clr	%o1
+	set	trap, %o2
+	mov	%g2, %o3
+	ba	%xcc, tl1_trap
+	 mov	T_DATA_MISS | T_KERNEL, %o0
+END(tl0_dmmu_miss_trap)
+
+	.macro	tl0_dmmu_prot
+	ba,a	%xcc, tl0_dmmu_prot_1
+	 nop
+	.align	128
+	.endm
+
+ENTRY(tl0_dmmu_prot_1)
+	/*
+	 * Load the context and the virtual page number from the tag access
+	 * register.  We ignore the context.
+	 */
+	wr	%g0, ASI_DMMU, %asi
+	ldxa	[%g0 + AA_DMMU_TAR] %asi, %g1
+
+	/*
+	 * Initialize the page size walker.
+	 */
+tl1_dmmu_prot_user:
+	mov	TS_MIN, %g2
+
+	/*
+	 * Loop over all supported page sizes.
+	 */
+
+	/*
+	 * Compute the page shift for the page size we are currently looking
+	 * for.
+	 */
+1:	add	%g2, %g2, %g3
+	add	%g3, %g2, %g3
+	add	%g3, PAGE_SHIFT, %g3
+
+	/*
+	 * Extract the virtual page number from the contents of the tag
+	 * access register.
+	 */
+	srlx	%g1, %g3, %g3
+
+	/*
+	 * Compute the TTE bucket address.
+	 */
+	ldxa	[%g0 + AA_DMMU_TSB] %asi, %g5
+	and	%g3, TSB_BUCKET_MASK, %g4
+	sllx	%g4, TSB_BUCKET_SHIFT + TTE_SHIFT, %g4
+	add	%g4, %g5, %g4
+
+	/*
+	 * Compute the TTE tag target.
+	 */
+	sllx	%g3, TV_SIZE_BITS, %g3
+	or	%g3, %g2, %g3
+
+	/*
+	 * Loop over the TTEs in this bucket.
+	 */
+
+	/*
+	 * Load the TTE.  Note that this instruction may fault, clobbering
+	 * the contents of the tag access register, %g5, %g6, and %g7.  We
+	 * do not use %g5, and %g6 and %g7 are not used until this instruction
+	 * completes successfully.
+	 */
+2:	ldda	[%g4] ASI_NUCLEUS_QUAD_LDD, %g6 /*, %g7 */
+
+	/*
+	 * Check that it's valid and writable and that the virtual page
+	 * numbers match.
+	 */
+	brgez,pn %g7, 4f
+	 andcc	%g7, TD_SW, %g0
+	bz,pn	%xcc, 4f
+	 cmp	%g3, %g6
+	bne,pn	%xcc, 4f
+	 nop
+
+	/*
+	 * Set the hardware write bit.
+	 */
+	TTE_SET_W(%g4, %g2, %g3, a, ASI_N)
+
+	/*
+	 * Delete the old TLB entry and clear the SFSR.
+	 */
+	srlx	%g1, PAGE_SHIFT, %g3
+	sllx	%g3, PAGE_SHIFT, %g3
+	stxa	%g0, [%g3] ASI_DMMU_DEMAP
+	stxa	%g0, [%g0 + AA_DMMU_SFSR] %asi
+	membar	#Sync
+
+	/*
+	 * May have become invalid during casxa, in which case start over.
+	 */
+	brgez,pn %g2, 3f
+	 or	%g2, TD_W, %g2
+
+	/*
+	 * Load the TTE data into the TLB and retry the instruction.
+	 */
+	stxa	%g1, [%g0 + AA_DMMU_TAR] %asi
+	stxa	%g2, [%g0] ASI_DTLB_DATA_IN_REG
+3:	retry
+
+	/*
+	 * Check the low bits to see if we've finished the bucket.
+	 */
+4:	add	%g4, 1 << TTE_SHIFT, %g4
+	andcc	%g4, (1 << (TSB_BUCKET_SHIFT + TTE_SHIFT)) - 1, %g0
+	bnz,pt	%xcc, 2b
+	 EMPTY
+
+	/*
+	 * See if we just checked the largest page size, and advance to the
+	 * next one if not.
+	 */
+	 cmp	%g2, TS_MAX
+	bne,pt	%xcc, 1b
+	 add	%g2, 1, %g2
+
+	/*
+	 * Not in user TSB, call C code.
+	 */
+	ba,a	%xcc, tl0_dmmu_prot_trap
+	 nop
+END(tl0_dmmu_prot_1)
+
+ENTRY(tl0_dmmu_prot_trap)
+	/*
+	 * Put back the contents of the tag access register, in case we
+	 * faulted.
+	 */
+	stxa	%g1, [%g0 + AA_DMMU_TAR] %asi
+	membar	#Sync
+
+	/*
+	 * Switch to alternate globals.
+	 */
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	/*
+	 * Check if we actually came from the kernel.
+	 */
+	rdpr	%tl, %g1
+	cmp	%g1, 1
+	bgt,a,pn %xcc, 1f
+	 nop
+
+	/*
+	 * Load the SFAR, SFSR and TAR.
+	 */
+	ldxa	[%g0 + AA_DMMU_TAR] %asi, %g2
+	ldxa	[%g0 + AA_DMMU_SFAR] %asi, %g3
+	ldxa	[%g0 + AA_DMMU_SFSR] %asi, %g4
+	stxa	%g0, [%g0 + AA_DMMU_SFSR] %asi
+	membar	#Sync
+
+	/*
+	 * Save the MMU registers and call common trap code.
+	 */
+	tl0_split
+	clr	%o1
+	set	trap, %o2
+	mov	%g2, %o3
+	mov	%g3, %o4
+	mov	%g4, %o5
+	ba	%xcc, tl0_utrap
+	 mov	T_DATA_PROTECTION, %o0
+
+	/*
+	 * Handle faults during window spill/fill.
+	 */
+1:	RESUME_SPILLFILL_MMU_CLR_SFSR
+
+	/*
+	 * Load the SFAR, SFSR and TAR.  Clear the SFSR.
+	 */
+	ldxa	[%g0 + AA_DMMU_TAR] %asi, %g2
+	ldxa	[%g0 + AA_DMMU_SFAR] %asi, %g3
+	ldxa	[%g0 + AA_DMMU_SFSR] %asi, %g4
+	stxa	%g0, [%g0 + AA_DMMU_SFSR] %asi
+	membar	#Sync
+
+	tl1_split
+	clr	%o1
+	set	trap, %o2
+	mov	%g2, %o3
+	mov	%g3, %o4
+	mov	%g4, %o5
+	ba	%xcc, tl1_trap
+	 mov	T_DATA_PROTECTION | T_KERNEL, %o0
+END(tl0_dmmu_prot_trap)
+
+	.macro	tl0_spill_0_n
+	wr	%g0, ASI_AIUP, %asi
+	SPILL(stxa, %sp + SPOFF, 8, %asi)
+	saved
+	retry
+	.align	32
+	RSF_TRAP(T_SPILL)
+	RSF_TRAP(T_SPILL)
+	.endm
+
+	.macro	tl0_spill_1_n
+	wr	%g0, ASI_AIUP, %asi
+	SPILL(stwa, %sp, 4, %asi)
+	saved
+	retry
+	.align	32
+	RSF_TRAP(T_SPILL)
+	RSF_TRAP(T_SPILL)
+	.endm
+
+	.macro	tl0_fill_0_n
+	wr	%g0, ASI_AIUP, %asi
+	FILL(ldxa, %sp + SPOFF, 8, %asi)
+	restored
+	retry
+	.align	32
+	RSF_TRAP(T_FILL)
+	RSF_TRAP(T_FILL)
+	.endm
+
+	.macro	tl0_fill_1_n
+	wr	%g0, ASI_AIUP, %asi
+	FILL(lduwa, %sp, 4, %asi)
+	restored
+	retry
+	.align	32
+	RSF_TRAP(T_FILL)
+	RSF_TRAP(T_FILL)
+	.endm
+
+ENTRY(tl0_sftrap)
+	rdpr	%tstate, %g1
+	and	%g1, TSTATE_CWP_MASK, %g1
+	wrpr	%g1, 0, %cwp
+	tl0_split
+	clr	%o1
+	set	trap, %o2
+	ba	%xcc, tl0_trap
+	 mov	%g2, %o0
+END(tl0_sftrap)
+
+	.macro	tl0_spill_bad	count
+	.rept	\count
+	sir
+	.align	128
+	.endr
+	.endm
+
+	.macro	tl0_fill_bad	count
+	.rept	\count
+	sir
+	.align	128
+	.endr
+	.endm
+
+	.macro	tl0_syscall
+	tl0_split
+	clr	%o1
+	set	syscall, %o2
+	ba	%xcc, tl0_trap
+	 mov	T_SYSCALL, %o0
+	.align	32
+	.endm
+
+	.macro	tl0_fp_restore
+	ba,a	%xcc, tl0_fp_restore
+	 nop
+	.align	32
+	.endm
+
+ENTRY(tl0_fp_restore)
+	ldx	[PCB_REG + PCB_FLAGS], %g1
+	andn	%g1, PCB_FEF, %g1
+	stx	%g1, [PCB_REG + PCB_FLAGS]
+
+	wr	%g0, FPRS_FEF, %fprs
+	wr	%g0, ASI_BLK_S, %asi
+	ldda	[PCB_REG + PCB_UFP + (0 * 64)] %asi, %f0
+	ldda	[PCB_REG + PCB_UFP + (1 * 64)] %asi, %f16
+	ldda	[PCB_REG + PCB_UFP + (2 * 64)] %asi, %f32
+	ldda	[PCB_REG + PCB_UFP + (3 * 64)] %asi, %f48
+	membar	#Sync
+	done
+END(tl0_fp_restore)
+
+	.macro	tl1_insn_excptn
+	wrpr	%g0, PSTATE_ALT, %pstate
+	wr	%g0, ASI_IMMU, %asi
+	rdpr	%tpc, %g3
+	ldxa	[%g0 + AA_IMMU_SFSR] %asi, %g4
+	/*
+	 * XXX in theory, a store to AA_IMMU_SFSR must be immediately
+	 * followed by a DONE, FLUSH or RETRY for USIII.  In practice,
+	 * this triggers a RED state exception though.
+	 */
+	stxa	%g0, [%g0 + AA_IMMU_SFSR] %asi
+	membar	#Sync
+	ba	%xcc, tl1_insn_exceptn_trap
+	 mov	T_INSTRUCTION_EXCEPTION | T_KERNEL, %g2
+	.align	32
+	.endm
+
+ENTRY(tl1_insn_exceptn_trap)
+	tl1_split
+	clr	%o1
+	set	trap, %o2
+	mov	%g3, %o4
+	mov	%g4, %o5
+	ba	%xcc, tl1_trap
+	 mov	%g2, %o0
+END(tl1_insn_exceptn_trap)
+
+	.macro	tl1_fp_disabled
+	ba,a	%xcc, tl1_fp_disabled_1
+	 nop
+	.align	32
+	.endm
+
+ENTRY(tl1_fp_disabled_1)
+	rdpr	%tpc, %g1
+	set	fpu_fault_begin, %g2
+	sub	%g1, %g2, %g1
+	cmp	%g1, fpu_fault_size
+	bgeu,a,pn %xcc, 1f
+	 nop
+
+	wr	%g0, FPRS_FEF, %fprs
+	wr	%g0, ASI_BLK_S, %asi
+	ldda	[PCB_REG + PCB_KFP + (0 * 64)] %asi, %f0
+	ldda	[PCB_REG + PCB_KFP + (1 * 64)] %asi, %f16
+	ldda	[PCB_REG + PCB_KFP + (2 * 64)] %asi, %f32
+	ldda	[PCB_REG + PCB_KFP + (3 * 64)] %asi, %f48
+	membar	#Sync
+	retry
+
+1:	tl1_split
+	clr	%o1
+	set	trap, %o2
+	ba	%xcc, tl1_trap
+	 mov	T_FP_DISABLED | T_KERNEL, %o0
+END(tl1_fp_disabled_1)
+
+	.macro	tl1_data_excptn
+	wrpr	%g0, PSTATE_ALT, %pstate
+	ba,a	%xcc, tl1_data_excptn_trap
+	 nop
+	.align	32
+	.endm
+
+ENTRY(tl1_data_excptn_trap)
+	RESUME_SPILLFILL_MMU_CLR_SFSR
+	ba	%xcc, tl1_sfsr_trap
+	 mov	T_DATA_EXCEPTION | T_KERNEL, %g2
+END(tl1_data_excptn_trap)
+
+	.macro	tl1_align
+	wrpr	%g0, PSTATE_ALT, %pstate
+	ba,a	%xcc, tl1_align_trap
+	 nop
+	.align	32
+	.endm
+
+ENTRY(tl1_align_trap)
+	RESUME_SPILLFILL_ALIGN
+	ba	%xcc, tl1_sfsr_trap
+	 mov	T_MEM_ADDRESS_NOT_ALIGNED | T_KERNEL, %g2
+END(tl1_align_trap)
+
+ENTRY(tl1_sfsr_trap)
+	wr	%g0, ASI_DMMU, %asi
+	ldxa	[%g0 + AA_DMMU_SFAR] %asi, %g3
+	ldxa	[%g0 + AA_DMMU_SFSR] %asi, %g4
+	stxa	%g0, [%g0 + AA_DMMU_SFSR] %asi
+	membar	#Sync
+
+	tl1_split
+	clr	%o1
+	set	trap, %o2
+	mov	%g3, %o4
+	mov	%g4, %o5
+	ba	%xcc, tl1_trap
+	 mov	%g2, %o0
+END(tl1_sfsr_trap)
+
+	.macro	tl1_intr level, mask
+	tl1_split
+	set	\mask, %o1
+	ba	%xcc, tl1_intr
+	 mov	\level, %o0
+	.align	32
+	.endm
+
+	.macro	tl1_intr_level
+	INTR_LEVEL(1)
+	.endm
+
+	.macro	tl1_immu_miss
+	/*
+	 * Load the context and the virtual page number from the tag access
+	 * register.  We ignore the context.
+	 */
+	wr	%g0, ASI_IMMU, %asi
+	ldxa	[%g0 + AA_IMMU_TAR] %asi, %g5
+
+	/*
+	 * Compute the address of the TTE.  The TSB mask and address of the
+	 * TSB are patched at startup.
+	 */
+	.globl	tl1_immu_miss_patch_tsb_1
+tl1_immu_miss_patch_tsb_1:
+	sethi	%uhi(TSB_KERNEL), %g6
+	or	%g6, %ulo(TSB_KERNEL), %g6
+	sllx	%g6, 32, %g6
+	sethi	%hi(TSB_KERNEL), %g7
+	or	%g7, %g6, %g7
+	.globl	tl1_immu_miss_patch_tsb_mask_1
+tl1_immu_miss_patch_tsb_mask_1:
+	sethi	%hi(TSB_KERNEL_MASK), %g6
+	or	%g6, %lo(TSB_KERNEL_MASK), %g6
+
+	srlx	%g5, TAR_VPN_SHIFT, %g5
+	and	%g5, %g6, %g6
+	sllx	%g6, TTE_SHIFT, %g6
+	add	%g6, %g7, %g6
+
+	/*
+	 * Load the TTE.
+	 */
+	.globl	tl1_immu_miss_patch_quad_ldd_1
+tl1_immu_miss_patch_quad_ldd_1:
+	ldda	[%g6] TSB_QUAD_LDD, %g6 /*, %g7 */
+
+	/*
+	 * Check that it's valid and executable and that the virtual page
+	 * numbers match.
+	 */
+	brgez,pn %g7, tl1_immu_miss_trap
+	 andcc	%g7, TD_EXEC, %g0
+	bz,pn	%xcc, tl1_immu_miss_trap
+	 srlx	%g6, TV_SIZE_BITS, %g6
+	cmp	%g5, %g6
+	bne,pn	%xcc, tl1_immu_miss_trap
+	 EMPTY
+
+	/*
+	 * Set the reference bit if it's currently clear.
+	 */
+	 andcc	%g7, TD_REF, %g0
+	bz,a,pn	%xcc, tl1_immu_miss_set_ref
+	 nop
+
+	/*
+	 * Load the TTE data into the TLB and retry the instruction.
+	 */
+	stxa	%g7, [%g0] ASI_ITLB_DATA_IN_REG
+	retry
+	.align	128
+	.endm
+
+ENTRY(tl1_immu_miss_set_ref)
+	/*
+	 * Recompute the TTE address, which we clobbered loading the TTE.
+	 * The TSB mask and address of the TSB are patched at startup.
+	 */
+	.globl	tl1_immu_miss_patch_tsb_2
+tl1_immu_miss_patch_tsb_2:
+	sethi	%uhi(TSB_KERNEL), %g6
+	or	%g6, %ulo(TSB_KERNEL), %g6
+	sllx	%g6, 32, %g6
+	sethi	%hi(TSB_KERNEL), %g7
+	or	%g7, %g6, %g7
+	.globl	tl1_immu_miss_patch_tsb_mask_2
+tl1_immu_miss_patch_tsb_mask_2:
+	sethi	%hi(TSB_KERNEL_MASK), %g6
+	or	%g6, %lo(TSB_KERNEL_MASK), %g6
+
+	and	%g5, %g6, %g5
+	sllx	%g5, TTE_SHIFT, %g5
+	add	%g5, %g7, %g5
+
+	/*
+	 * Set the reference bit.
+	 */
+	.globl	tl1_immu_miss_patch_asi_1
+tl1_immu_miss_patch_asi_1:
+	wr	%g0, TSB_ASI, %asi
+	TTE_SET_REF(%g5, %g6, %g7, a, %asi)
+
+	/*
+	 * May have become invalid during casxa, in which case start over.
+	 */
+	brgez,pn %g6, 1f
+	 nop
+
+	/*
+	 * Load the TTE data into the TLB and retry the instruction.
+	 */
+	stxa	%g6, [%g0] ASI_ITLB_DATA_IN_REG
+1:	retry
+END(tl1_immu_miss_set_ref)
+
+ENTRY(tl1_immu_miss_trap)
+	/*
+	 * Switch to alternate globals.
+	 */
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	ldxa	[%g0 + AA_IMMU_TAR] %asi, %g2
+
+	tl1_split
+	clr	%o1
+	set	trap, %o2
+	mov	%g2, %o3
+	ba	%xcc, tl1_trap
+	 mov	T_INSTRUCTION_MISS | T_KERNEL, %o0
+END(tl1_immu_miss_trap)
+
+	.macro	tl1_dmmu_miss
+	/*
+	 * Load the context and the virtual page number from the tag access
+	 * register.
+	 */
+	wr	%g0, ASI_DMMU, %asi
+	ldxa	[%g0 + AA_DMMU_TAR] %asi, %g5
+
+	/*
+	 * Extract the context from the contents of the tag access register.
+	 * If it's non-zero this is a fault on a user address.  Note that the
+	 * faulting address is passed in %g1.
+	 */
+	sllx	%g5, 64 - TAR_VPN_SHIFT, %g6
+	brnz,a,pn %g6, tl1_dmmu_miss_user
+	 mov	%g5, %g1
+
+	/*
+	 * Check for the direct mapped physical region.  These addresses have
+	 * the high bit set so they are negative.
+	 */
+	brlz,pn %g5, tl1_dmmu_miss_direct
+	 EMPTY
+
+	/*
+	 * Compute the address of the TTE.  The TSB mask and address of the
+	 * TSB are patched at startup.
+	 */
+	.globl	tl1_dmmu_miss_patch_tsb_1
+tl1_dmmu_miss_patch_tsb_1:
+	sethi	%uhi(TSB_KERNEL), %g6
+	or	%g6, %ulo(TSB_KERNEL), %g6
+	sllx	%g6, 32, %g6
+	sethi	%hi(TSB_KERNEL), %g7
+	or	%g7, %g6, %g7
+	.globl	tl1_dmmu_miss_patch_tsb_mask_1
+tl1_dmmu_miss_patch_tsb_mask_1:
+	sethi	%hi(TSB_KERNEL_MASK), %g6
+	or	%g6, %lo(TSB_KERNEL_MASK), %g6
+
+	srlx	%g5, TAR_VPN_SHIFT, %g5
+	and	%g5, %g6, %g6
+	sllx	%g6, TTE_SHIFT, %g6
+	add	%g6, %g7, %g6
+
+	/*
+	 * Load the TTE.
+	 */
+	.globl	tl1_dmmu_miss_patch_quad_ldd_1
+tl1_dmmu_miss_patch_quad_ldd_1:
+	ldda	[%g6] TSB_QUAD_LDD, %g6 /*, %g7 */
+
+	/*
+	 * Check that it's valid and that the virtual page numbers match.
+	 */
+	brgez,pn %g7, tl1_dmmu_miss_trap
+	 srlx	%g6, TV_SIZE_BITS, %g6
+	cmp	%g5, %g6
+	bne,pn %xcc, tl1_dmmu_miss_trap
+	 EMPTY
+
+	/*
+	 * Set the reference bit if it's currently clear.
+	 */
+	 andcc	%g7, TD_REF, %g0
+	bz,a,pt	%xcc, tl1_dmmu_miss_set_ref
+	 nop
+
+	/*
+	 * Load the TTE data into the TLB and retry the instruction.
+	 */
+	stxa	%g7, [%g0] ASI_DTLB_DATA_IN_REG
+	retry
+	.align	128
+	.endm
+
+ENTRY(tl1_dmmu_miss_set_ref)
+	/*
+	 * Recompute the TTE address, which we clobbered loading the TTE.
+	 * The TSB mask and address of the TSB are patched at startup.
+	 */
+	.globl	tl1_dmmu_miss_patch_tsb_mask_2
+tl1_dmmu_miss_patch_tsb_2:
+	sethi	%uhi(TSB_KERNEL), %g6
+	or	%g6, %ulo(TSB_KERNEL), %g6
+	sllx	%g6, 32, %g6
+	sethi	%hi(TSB_KERNEL), %g7
+	or	%g7, %g6, %g7
+	.globl	tl1_dmmu_miss_patch_tsb_2
+tl1_dmmu_miss_patch_tsb_mask_2:
+	sethi	%hi(TSB_KERNEL_MASK), %g6
+	or	%g6, %lo(TSB_KERNEL_MASK), %g6
+
+	and	%g5, %g6, %g5
+	sllx	%g5, TTE_SHIFT, %g5
+	add	%g5, %g7, %g5
+
+	/*
+	 * Set the reference bit.
+	 */
+	.globl	tl1_dmmu_miss_patch_asi_1
+tl1_dmmu_miss_patch_asi_1:
+	wr	%g0, TSB_ASI, %asi
+	TTE_SET_REF(%g5, %g6, %g7, a, %asi)
+
+	/*
+	 * May have become invalid during casxa, in which case start over.
+	 */
+	brgez,pn %g6, 1f
+	 nop
+
+	/*
+	 * Load the TTE data into the TLB and retry the instruction.
+	 */
+	stxa	%g6, [%g0] ASI_DTLB_DATA_IN_REG
+1:	retry
+END(tl1_dmmu_miss_set_ref)
+
+ENTRY(tl1_dmmu_miss_trap)
+	/*
+	 * Switch to alternate globals.
+	 */
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	ldxa	[%g0 + AA_DMMU_TAR] %asi, %g2
+
+	KSTACK_CHECK
+
+	tl1_split
+	clr	%o1
+	set	trap, %o2
+	mov	%g2, %o3
+	ba	%xcc, tl1_trap
+	 mov	T_DATA_MISS | T_KERNEL, %o0
+END(tl1_dmmu_miss_trap)
+
+ENTRY(tl1_dmmu_miss_direct)
+	/*
+	 * Mask off the high bits of the virtual address to get the physical
+	 * address, and or in the TTE bits.  The virtual address bits that
+	 * correspond to the TTE valid and page size bits are left set, so
+	 * they don't have to be included in the TTE bits below.  We know they
+	 * are set because the virtual address is in the upper va hole.
+	 * NB: if we are taking advantage of the ASI_ATOMIC_QUAD_LDD_PHYS
+	 * and we get a miss on the directly accessed kernel TSB we must not
+	 * set TD_CV in order to access it uniformly bypassing the D$.
+	 */
+	setx	TLB_DIRECT_ADDRESS_MASK, %g7, %g4
+	and	%g5, %g4, %g4
+	setx	TLB_DIRECT_TO_TTE_MASK, %g7, %g6
+	and	%g5, %g6, %g5
+	.globl	tl1_dmmu_miss_direct_patch_tsb_phys_1
+tl1_dmmu_miss_direct_patch_tsb_phys_1:
+	sethi	%uhi(TSB_KERNEL_PHYS), %g3
+	or	%g3, %ulo(TSB_KERNEL_PHYS), %g3
+	sllx	%g3, 32, %g3
+	sethi	%hi(TSB_KERNEL_PHYS), %g3
+	or	%g7, %g3, %g7
+	cmp	%g4, %g7
+	bl,pt	%xcc, 1f
+	 or	%g5, TD_CP | TD_W, %g5
+	.globl	tl1_dmmu_miss_direct_patch_tsb_phys_end_1
+tl1_dmmu_miss_direct_patch_tsb_phys_end_1:
+	sethi	%uhi(TSB_KERNEL_PHYS_END), %g3
+	or	%g3, %ulo(TSB_KERNEL_PHYS_END), %g3
+	sllx	%g3, 32, %g3
+	sethi	%hi(TSB_KERNEL_PHYS_END), %g7
+	or	%g7, %g3, %g7
+	cmp	%g4, %g7
+	bg,a,pt	%xcc, 1f
+	 nop
+	ba,pt	%xcc, 2f
+	 nop
+1:	or	%g5, TD_CV, %g5
+
+	/*
+	 * Load the TTE data into the TLB and retry the instruction.
+	 */
+2:	stxa	%g5, [%g0] ASI_DTLB_DATA_IN_REG
+	retry
+END(tl1_dmmu_miss_direct)
+
+	.macro	tl1_dmmu_prot
+	ba,a	%xcc, tl1_dmmu_prot_1
+	 nop
+	.align	128
+	.endm
+
+ENTRY(tl1_dmmu_prot_1)
+	/*
+	 * Load the context and the virtual page number from the tag access
+	 * register.
+	 */
+	wr	%g0, ASI_DMMU, %asi
+	ldxa	[%g0 + AA_DMMU_TAR] %asi, %g5
+
+	/*
+	 * Extract the context from the contents of the tag access register.
+	 * If it's non-zero this is a fault on a user address.  Note that the
+	 * faulting address is passed in %g1.
+	 */
+	sllx	%g5, 64 - TAR_VPN_SHIFT, %g6
+	brnz,a,pn %g6, tl1_dmmu_prot_user
+	 mov	%g5, %g1
+
+	/*
+	 * Compute the address of the TTE.  The TSB mask and address of the
+	 * TSB are patched at startup.
+	 */
+	.globl	tl1_dmmu_prot_patch_tsb_1
+tl1_dmmu_prot_patch_tsb_1:
+	sethi	%uhi(TSB_KERNEL), %g6
+	or	%g6, %ulo(TSB_KERNEL), %g6
+	sllx	%g6, 32, %g6
+	sethi	%hi(TSB_KERNEL), %g7
+	or	%g7, %g6, %g7
+	.globl	tl1_dmmu_prot_patch_tsb_mask_1
+tl1_dmmu_prot_patch_tsb_mask_1:
+	sethi	%hi(TSB_KERNEL_MASK), %g6
+	or	%g6, %lo(TSB_KERNEL_MASK), %g6
+
+	srlx	%g5, TAR_VPN_SHIFT, %g5
+	and	%g5, %g6, %g6
+	sllx	%g6, TTE_SHIFT, %g6
+	add	%g6, %g7, %g6
+
+	/*
+	 * Load the TTE.
+	 */
+	.globl	tl1_dmmu_prot_patch_quad_ldd_1
+tl1_dmmu_prot_patch_quad_ldd_1:
+	ldda	[%g6] TSB_QUAD_LDD, %g6 /*, %g7 */
+
+	/*
+	 * Check that it's valid and writeable and that the virtual page
+	 * numbers match.
+	 */
+	brgez,pn %g7, tl1_dmmu_prot_trap
+	 andcc	%g7, TD_SW, %g0
+	bz,pn	%xcc, tl1_dmmu_prot_trap
+	 srlx	%g6, TV_SIZE_BITS, %g6
+	cmp	%g5, %g6
+	bne,pn	%xcc, tl1_dmmu_prot_trap
+	 EMPTY
+
+	/*
+	 * Delete the old TLB entry and clear the SFSR.
+	 */
+	 sllx	%g5, TAR_VPN_SHIFT, %g6
+	or	%g6, TLB_DEMAP_NUCLEUS, %g6
+	stxa	%g0, [%g6] ASI_DMMU_DEMAP
+	stxa	%g0, [%g0 + AA_DMMU_SFSR] %asi
+	membar	#Sync
+
+	/*
+	 * Recompute the TTE address, which we clobbered loading the TTE.
+	 * The TSB mask and address of the TSB are patched at startup.
+	 */
+	.globl	tl1_dmmu_prot_patch_tsb_2
+tl1_dmmu_prot_patch_tsb_2:
+	sethi	%uhi(TSB_KERNEL), %g6
+	or	%g6, %ulo(TSB_KERNEL), %g6
+	sllx	%g6, 32, %g6
+	sethi	%hi(TSB_KERNEL), %g7
+	or	%g7, %g6, %g7
+	.globl	tl1_dmmu_prot_patch_tsb_mask_2
+tl1_dmmu_prot_patch_tsb_mask_2:
+	sethi	%hi(TSB_KERNEL_MASK), %g6
+	or	%g6, %lo(TSB_KERNEL_MASK), %g6
+	and	%g5, %g6, %g5
+	sllx	%g5, TTE_SHIFT, %g5
+	add	%g5, %g7, %g5
+
+	/*
+	 * Set the hardware write bit.
+	 */
+	.globl	tl1_dmmu_prot_patch_asi_1
+tl1_dmmu_prot_patch_asi_1:
+	wr	%g0, TSB_ASI, %asi
+	TTE_SET_W(%g5, %g6, %g7, a, %asi)
+
+	/*
+	 * May have become invalid during casxa, in which case start over.
+	 */
+	brgez,pn %g6, 1f
+	 or	%g6, TD_W, %g6
+
+	/*
+	 * Load the TTE data into the TLB and retry the instruction.
+	 */
+	stxa	%g6, [%g0] ASI_DTLB_DATA_IN_REG
+1:	retry
+END(tl1_dmmu_prot_1)
+
+ENTRY(tl1_dmmu_prot_trap)
+	/*
+	 * Switch to alternate globals.
+	 */
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	/*
+	 * Load the SFAR, SFSR and TAR.  Clear the SFSR.
+	 */
+	ldxa	[%g0 + AA_DMMU_TAR] %asi, %g2
+	ldxa	[%g0 + AA_DMMU_SFAR] %asi, %g3
+	ldxa	[%g0 + AA_DMMU_SFSR] %asi, %g4
+	stxa	%g0, [%g0 + AA_DMMU_SFSR] %asi
+	membar	#Sync
+
+	tl1_split
+	clr	%o1
+	set	trap, %o2
+	mov	%g2, %o3
+	mov	%g3, %o4
+	mov	%g4, %o5
+	ba	%xcc, tl1_trap
+	 mov	T_DATA_PROTECTION | T_KERNEL, %o0
+END(tl1_dmmu_prot_trap)
+
+	.macro	tl1_spill_0_n
+	SPILL(stx, %sp + SPOFF, 8, EMPTY)
+	saved
+	retry
+	.align	32
+	RSF_FATAL(T_SPILL)
+	RSF_FATAL(T_SPILL)
+	.endm
+
+	.macro	tl1_spill_2_n
+	wr	%g0, ASI_AIUP, %asi
+	SPILL(stxa, %sp + SPOFF, 8, %asi)
+	saved
+	retry
+	.align	32
+	RSF_SPILL_TOPCB
+	RSF_SPILL_TOPCB
+	.endm
+
+	.macro	tl1_spill_3_n
+	wr	%g0, ASI_AIUP, %asi
+	SPILL(stwa, %sp, 4, %asi)
+	saved
+	retry
+	.align	32
+	RSF_SPILL_TOPCB
+	RSF_SPILL_TOPCB
+	.endm
+
+	.macro	tl1_spill_7_n
+	btst	1, %sp
+	bnz,a,pn %xcc, tl1_spill_0_n
+	 nop
+	srl	%sp, 0, %sp
+	SPILL(stw, %sp, 4, EMPTY)
+	saved
+	retry
+	.align	32
+	RSF_FATAL(T_SPILL)
+	RSF_FATAL(T_SPILL)
+	.endm
+
+	.macro	tl1_spill_0_o
+	wr	%g0, ASI_AIUP, %asi
+	SPILL(stxa, %sp + SPOFF, 8, %asi)
+	saved
+	retry
+	.align	32
+	RSF_SPILL_TOPCB
+	RSF_SPILL_TOPCB
+	.endm
+
+	.macro	tl1_spill_1_o
+	wr	%g0, ASI_AIUP, %asi
+	SPILL(stwa, %sp, 4, %asi)
+	saved
+	retry
+	.align	32
+	RSF_SPILL_TOPCB
+	RSF_SPILL_TOPCB
+	.endm
+
+	.macro	tl1_spill_2_o
+	RSF_SPILL_TOPCB
+	.align	128
+	.endm
+
+	.macro	tl1_fill_0_n
+	FILL(ldx, %sp + SPOFF, 8, EMPTY)
+	restored
+	retry
+	.align	32
+	RSF_FATAL(T_FILL)
+	RSF_FATAL(T_FILL)
+	.endm
+
+	.macro	tl1_fill_2_n
+	wr	%g0, ASI_AIUP, %asi
+	FILL(ldxa, %sp + SPOFF, 8, %asi)
+	restored
+	retry
+	.align 32
+	RSF_FILL_MAGIC
+	RSF_FILL_MAGIC
+	.endm
+
+	.macro	tl1_fill_3_n
+	wr	%g0, ASI_AIUP, %asi
+	FILL(lduwa, %sp, 4, %asi)
+	restored
+	retry
+	.align 32
+	RSF_FILL_MAGIC
+	RSF_FILL_MAGIC
+	.endm
+
+	.macro	tl1_fill_7_n
+	btst	1, %sp
+	bnz,a,pt %xcc, tl1_fill_0_n
+	 nop
+	srl	%sp, 0, %sp
+	FILL(lduw, %sp, 4, EMPTY)
+	restored
+	retry
+	.align	32
+	RSF_FATAL(T_FILL)
+	RSF_FATAL(T_FILL)
+	.endm
+
+/*
+ * This is used to spill windows that are still occupied with user
+ * data on kernel entry to the pcb.
+ */
+ENTRY(tl1_spill_topcb)
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	/* Free some globals for our use. */
+	dec	24, ASP_REG
+	stx	%g1, [ASP_REG + 0]
+	stx	%g2, [ASP_REG + 8]
+	stx	%g3, [ASP_REG + 16]
+
+	ldx	[PCB_REG + PCB_NSAVED], %g1
+
+	sllx	%g1, PTR_SHIFT, %g2
+	add	%g2, PCB_REG, %g2
+	stx	%sp, [%g2 + PCB_RWSP]
+
+	sllx	%g1, RW_SHIFT, %g2
+	add	%g2, PCB_REG, %g2
+	SPILL(stx, %g2 + PCB_RW, 8, EMPTY)
+
+	inc	%g1
+	stx	%g1, [PCB_REG + PCB_NSAVED]
+
+#if KTR_COMPILE & KTR_TRAP
+	CATR(KTR_TRAP, "tl1_spill_topcb: pc=%#lx npc=%#lx sp=%#lx nsaved=%d"
+	   , %g1, %g2, %g3, 7, 8, 9)
+	rdpr	%tpc, %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	rdpr	%tnpc, %g2
+	stx	%g2, [%g1 + KTR_PARM2]
+	stx	%sp, [%g1 + KTR_PARM3]
+	ldx	[PCB_REG + PCB_NSAVED], %g2
+	stx	%g2, [%g1 + KTR_PARM4]
+9:
+#endif
+
+	saved
+
+	ldx	[ASP_REG + 16], %g3
+	ldx	[ASP_REG + 8], %g2
+	ldx	[ASP_REG + 0], %g1
+	inc	24, ASP_REG
+	retry
+END(tl1_spill_topcb)
+
+	.macro	tl1_spill_bad	count
+	.rept	\count
+	sir
+	.align	128
+	.endr
+	.endm
+
+	.macro	tl1_fill_bad	count
+	.rept	\count
+	sir
+	.align	128
+	.endr
+	.endm
+
+	.macro	tl1_soft	count
+	.rept	\count
+	tl1_gen	T_SOFT | T_KERNEL
+	.endr
+	.endm
+
+	.sect	.trap
+	.globl	tl_trap_begin
+tl_trap_begin:
+	nop
+
+	.align	0x8000
+	.globl	tl0_base
+
+tl0_base:
+	tl0_reserved	8				! 0x0-0x7
+tl0_insn_excptn:
+	tl0_insn_excptn					! 0x8
+	tl0_reserved	1				! 0x9
+tl0_insn_error:
+	tl0_gen		T_INSTRUCTION_ERROR		! 0xa
+	tl0_reserved	5				! 0xb-0xf
+tl0_insn_illegal:
+	tl0_gen		T_ILLEGAL_INSTRUCTION		! 0x10
+tl0_priv_opcode:
+	tl0_gen		T_PRIVILEGED_OPCODE		! 0x11
+	tl0_reserved	14				! 0x12-0x1f
+tl0_fp_disabled:
+	tl0_gen		T_FP_DISABLED			! 0x20
+tl0_fp_ieee:
+	tl0_gen		T_FP_EXCEPTION_IEEE_754		! 0x21
+tl0_fp_other:
+	tl0_gen		T_FP_EXCEPTION_OTHER		! 0x22
+tl0_tag_ovflw:
+	tl0_gen		T_TAG_OVERFLOW			! 0x23
+tl0_clean_window:
+	clean_window					! 0x24
+tl0_divide:
+	tl0_gen		T_DIVISION_BY_ZERO		! 0x28
+	tl0_reserved	7				! 0x29-0x2f
+tl0_data_excptn:
+	tl0_data_excptn					! 0x30
+	tl0_reserved	1				! 0x31
+tl0_data_error:
+	tl0_gen		T_DATA_ERROR			! 0x32
+	tl0_reserved	1				! 0x33
+tl0_align:
+	tl0_align					! 0x34
+tl0_align_lddf:
+	tl0_gen		T_RESERVED			! 0x35
+tl0_align_stdf:
+	tl0_gen		T_RESERVED			! 0x36
+tl0_priv_action:
+	tl0_gen		T_PRIVILEGED_ACTION		! 0x37
+	tl0_reserved	9				! 0x38-0x40
+tl0_intr_level:
+	tl0_intr_level					! 0x41-0x4f
+	tl0_reserved	16				! 0x50-0x5f
+tl0_intr_vector:
+	intr_vector					! 0x60
+tl0_watch_phys:
+	tl0_gen		T_PA_WATCHPOINT			! 0x61
+tl0_watch_virt:
+	tl0_gen		T_VA_WATCHPOINT			! 0x62
+tl0_ecc:
+	tl0_gen		T_CORRECTED_ECC_ERROR		! 0x63
+tl0_immu_miss:
+	tl0_immu_miss					! 0x64
+tl0_dmmu_miss:
+	tl0_dmmu_miss					! 0x68
+tl0_dmmu_prot:
+	tl0_dmmu_prot					! 0x6c
+	tl0_reserved	16				! 0x70-0x7f
+tl0_spill_0_n:
+	tl0_spill_0_n					! 0x80
+tl0_spill_1_n:
+	tl0_spill_1_n					! 0x84
+	tl0_spill_bad	14				! 0x88-0xbf
+tl0_fill_0_n:
+	tl0_fill_0_n					! 0xc0
+tl0_fill_1_n:
+	tl0_fill_1_n					! 0xc4
+	tl0_fill_bad	14				! 0xc8-0xff
+tl0_soft:
+	tl0_gen		T_SYSCALL			! 0x100
+	tl0_gen		T_BREAKPOINT			! 0x101
+	tl0_gen		T_DIVISION_BY_ZERO		! 0x102
+	tl0_reserved	1				! 0x103
+	tl0_gen		T_CLEAN_WINDOW			! 0x104
+	tl0_gen		T_RANGE_CHECK			! 0x105
+	tl0_gen		T_FIX_ALIGNMENT			! 0x106
+	tl0_gen		T_INTEGER_OVERFLOW		! 0x107
+	tl0_gen		T_SYSCALL			! 0x108
+	tl0_gen		T_SYSCALL			! 0x109
+	tl0_fp_restore					! 0x10a
+	tl0_reserved	5				! 0x10b-0x10f
+	tl0_gen		T_TRAP_INSTRUCTION_16		! 0x110
+	tl0_gen		T_TRAP_INSTRUCTION_17		! 0x111
+	tl0_gen		T_TRAP_INSTRUCTION_18		! 0x112
+	tl0_gen		T_TRAP_INSTRUCTION_19		! 0x113
+	tl0_gen		T_TRAP_INSTRUCTION_20		! 0x114
+	tl0_gen		T_TRAP_INSTRUCTION_21		! 0x115
+	tl0_gen		T_TRAP_INSTRUCTION_22		! 0x116
+	tl0_gen		T_TRAP_INSTRUCTION_23		! 0x117
+	tl0_gen		T_TRAP_INSTRUCTION_24		! 0x118
+	tl0_gen		T_TRAP_INSTRUCTION_25		! 0x119
+	tl0_gen		T_TRAP_INSTRUCTION_26		! 0x11a
+	tl0_gen		T_TRAP_INSTRUCTION_27		! 0x11b
+	tl0_gen		T_TRAP_INSTRUCTION_28		! 0x11c
+	tl0_gen		T_TRAP_INSTRUCTION_29		! 0x11d
+	tl0_gen		T_TRAP_INSTRUCTION_30		! 0x11e
+	tl0_gen		T_TRAP_INSTRUCTION_31		! 0x11f
+	tl0_reserved	32				! 0x120-0x13f
+	tl0_gen		T_SYSCALL			! 0x140
+	tl0_syscall					! 0x141
+	tl0_gen		T_SYSCALL			! 0x142
+	tl0_gen		T_SYSCALL			! 0x143
+	tl0_reserved	188				! 0x144-0x1ff
+
+tl1_base:
+	tl1_reserved	8				! 0x200-0x207
+tl1_insn_excptn:
+	tl1_insn_excptn					! 0x208
+	tl1_reserved	1				! 0x209
+tl1_insn_error:
+	tl1_gen		T_INSTRUCTION_ERROR		! 0x20a
+	tl1_reserved	5				! 0x20b-0x20f
+tl1_insn_illegal:
+	tl1_gen		T_ILLEGAL_INSTRUCTION		! 0x210
+tl1_priv_opcode:
+	tl1_gen		T_PRIVILEGED_OPCODE		! 0x211
+	tl1_reserved	14				! 0x212-0x21f
+tl1_fp_disabled:
+	tl1_fp_disabled					! 0x220
+tl1_fp_ieee:
+	tl1_gen		T_FP_EXCEPTION_IEEE_754		! 0x221
+tl1_fp_other:
+	tl1_gen		T_FP_EXCEPTION_OTHER		! 0x222
+tl1_tag_ovflw:
+	tl1_gen		T_TAG_OVERFLOW			! 0x223
+tl1_clean_window:
+	clean_window					! 0x224
+tl1_divide:
+	tl1_gen		T_DIVISION_BY_ZERO		! 0x228
+	tl1_reserved	7				! 0x229-0x22f
+tl1_data_excptn:
+	tl1_data_excptn					! 0x230
+	tl1_reserved	1				! 0x231
+tl1_data_error:
+	tl1_gen		T_DATA_ERROR			! 0x232
+	tl1_reserved	1				! 0x233
+tl1_align:
+	tl1_align					! 0x234
+tl1_align_lddf:
+	tl1_gen		T_RESERVED			! 0x235
+tl1_align_stdf:
+	tl1_gen		T_RESERVED			! 0x236
+tl1_priv_action:
+	tl1_gen		T_PRIVILEGED_ACTION		! 0x237
+	tl1_reserved	9				! 0x238-0x240
+tl1_intr_level:
+	tl1_intr_level					! 0x241-0x24f
+	tl1_reserved	16				! 0x250-0x25f
+tl1_intr_vector:
+	intr_vector					! 0x260
+tl1_watch_phys:
+	tl1_gen		T_PA_WATCHPOINT			! 0x261
+tl1_watch_virt:
+	tl1_gen		T_VA_WATCHPOINT			! 0x262
+tl1_ecc:
+	tl1_gen		T_CORRECTED_ECC_ERROR		! 0x263
+tl1_immu_miss:
+	tl1_immu_miss					! 0x264
+tl1_dmmu_miss:
+	tl1_dmmu_miss					! 0x268
+tl1_dmmu_prot:
+	tl1_dmmu_prot					! 0x26c
+	tl1_reserved	16				! 0x270-0x27f
+tl1_spill_0_n:
+	tl1_spill_0_n					! 0x280
+	tl1_spill_bad	1				! 0x284
+tl1_spill_2_n:
+	tl1_spill_2_n					! 0x288
+tl1_spill_3_n:
+	tl1_spill_3_n					! 0x28c
+	tl1_spill_bad	3				! 0x290-0x29b
+tl1_spill_7_n:
+	tl1_spill_7_n					! 0x29c
+tl1_spill_0_o:
+	tl1_spill_0_o					! 0x2a0
+tl1_spill_1_o:
+	tl1_spill_1_o					! 0x2a4
+tl1_spill_2_o:
+	tl1_spill_2_o					! 0x2a8
+	tl1_spill_bad	5				! 0x2ac-0x2bf
+tl1_fill_0_n:
+	tl1_fill_0_n					! 0x2c0
+	tl1_fill_bad	1				! 0x2c4
+tl1_fill_2_n:
+	tl1_fill_2_n					! 0x2c8
+tl1_fill_3_n:
+	tl1_fill_3_n					! 0x2cc
+	tl1_fill_bad	3				! 0x2d0-0x2db
+tl1_fill_7_n:
+	tl1_fill_7_n					! 0x2dc
+	tl1_fill_bad	8				! 0x2e0-0x2ff
+	tl1_reserved	1				! 0x300
+tl1_breakpoint:
+	tl1_gen		T_BREAKPOINT			! 0x301
+	tl1_gen		T_RSTRWP_PHYS			! 0x302
+	tl1_gen		T_RSTRWP_VIRT			! 0x303
+	tl1_reserved	252				! 0x304-0x3ff
+
+	.globl	tl_trap_end
+tl_trap_end:
+	nop
+
+/*
+ * User trap entry point
+ *
+ * void tl0_utrap(u_long type, u_long o1, u_long o2, u_long tar, u_long sfar,
+ *     u_long sfsr)
+ *
+ * This handles redirecting a trap back to usermode as a user trap.  The user
+ * program must have first registered a trap handler with the kernel using
+ * sysarch(SPARC_UTRAP_INSTALL).  The trap handler is passed enough state
+ * for it to return to the trapping code directly, it will not return through
+ * the kernel.  The trap type is passed in %o0, all out registers must be
+ * passed through to tl0_trap or to usermode untouched.  Note that the
+ * parameters passed in out registers may be used by the user trap handler.
+ * Do not change the registers they are passed in or you will break the ABI.
+ *
+ * If the trap type allows user traps, setup state to execute the user trap
+ * handler and bounce back to usermode, otherwise branch to tl0_trap.
+ */
+ENTRY(tl0_utrap)
+	/*
+	 * Check if the trap type allows user traps.
+	 */
+	cmp	%o0, UT_MAX
+	bge,a,pt %xcc, tl0_trap
+	 nop
+
+	/*
+	 * Load the user trap handler from the utrap table.
+	 */
+	ldx	[PCPU(CURTHREAD)], %l0
+	ldx	[%l0 + TD_PROC], %l0
+	ldx	[%l0 + P_MD + MD_UTRAP], %l0
+	brz,pt	%l0, tl0_trap
+	 sllx	%o0, PTR_SHIFT, %l1
+	ldx	[%l0 + %l1], %l0
+	brz,a,pt %l0, tl0_trap
+	 nop
+
+	/*
+	 * If the save we did on entry to the kernel had to spill a window
+	 * to the pcb, pretend we took a spill trap instead.  Any windows
+	 * that are in the pcb must be copied out or the fill handler will
+	 * not be able to find them, since the user trap handler returns
+	 * directly to the trapping code.  Note that we only support precise
+	 * user traps, which implies that the condition that caused the trap
+	 * in the first place is still valid, so it will occur again when we
+	 * re-execute the trapping instruction.
+	 */
+	ldx	[PCB_REG + PCB_NSAVED], %l1
+	brnz,a,pn %l1, tl0_trap
+	 mov	T_SPILL, %o0
+
+	/*
+	 * Pass %fsr in %l4, %tstate in %l5, %tpc in %l6 and %tnpc in %l7.
+	 * The ABI specifies only %l6 and %l7, but we need to pass %fsr or
+	 * it may be clobbered by an interrupt before the user trap code
+	 * can read it, and we must pass %tstate in order to restore %ccr
+	 * and %asi.  The %fsr must be stored to memory, so we use the
+	 * temporary stack for that.
+	 */
+	rd	%fprs, %l1
+	or	%l1, FPRS_FEF, %l2
+	wr	%l2, 0, %fprs
+	dec	8, ASP_REG
+	stx	%fsr, [ASP_REG]
+	ldx	[ASP_REG], %l4
+	inc	8, ASP_REG
+	wr	%l1, 0, %fprs
+
+	rdpr	%tstate, %l5
+	rdpr	%tpc, %l6
+	rdpr	%tnpc, %l7
+
+	/*
+	 * Setup %tnpc to return to.
+	 */
+	wrpr	%l0, 0, %tnpc
+
+	/*
+	 * Setup %wstate for return, clear WSTATE_TRANSITION.
+	 */
+	rdpr	%wstate, %l1
+	and	%l1, WSTATE_NORMAL_MASK, %l1
+	wrpr	%l1, 0, %wstate
+
+	/*
+	 * Setup %tstate for return, change the saved cwp to point to the
+	 * current window instead of the window at the time of the trap.
+	 */
+	andn	%l5, TSTATE_CWP_MASK, %l1
+	rdpr	%cwp, %l2
+	wrpr	%l1, %l2, %tstate
+
+	/*
+	 * Setup %sp.  Userland processes will crash if this is not setup.
+	 */
+	sub	%fp, CCFSZ, %sp
+
+	/*
+	 * Execute the user trap handler.
+	 */
+	done
+END(tl0_utrap)
+
+/*
+ * (Real) User trap entry point
+ *
+ * void tl0_trap(u_int type, u_long o1, u_long o2, u_long tar, u_long sfsr,
+ *     u_int sfsr)
+ *
+ * The following setup has been performed:
+ *	- the windows have been split and the active user window has been saved
+ *	  (maybe just to the pcb)
+ *	- we are on alternate globals and interrupts are disabled
+ *
+ * We switch to the kernel stack, build a trapframe, switch to normal
+ * globals, enable interrupts and call trap.
+ *
+ * NOTE: We must be very careful setting up the per-cpu pointer.  We know that
+ * it has been pre-set in alternate globals, so we read it from there and setup
+ * the normal %g7 *before* enabling interrupts.  This avoids any possibility
+ * of cpu migration and using the wrong pcpup.
+ */
+ENTRY(tl0_trap)
+	/*
+	 * Force kernel store order.
+	 */
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	rdpr	%tstate, %l0
+	rdpr	%tpc, %l1
+	rdpr	%tnpc, %l2
+	rd	%y, %l3
+	rd	%fprs, %l4
+	rdpr	%wstate, %l5
+
+#if KTR_COMPILE & KTR_TRAP
+	CATR(KTR_TRAP,
+	    "tl0_trap: td=%p type=%#x pil=%#lx pc=%#lx npc=%#lx sp=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	ldx	[PCPU(CURTHREAD)], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	stx	%o0, [%g1 + KTR_PARM2]
+	rdpr	%pil, %g2
+	stx	%g2, [%g1 + KTR_PARM3]
+	stx	%l1, [%g1 + KTR_PARM4]
+	stx	%l2, [%g1 + KTR_PARM5]
+	stx	%i6, [%g1 + KTR_PARM6]
+9:
+#endif
+
+1:	and	%l5, WSTATE_NORMAL_MASK, %l5
+	sllx	%l5, WSTATE_OTHER_SHIFT, %l5
+	wrpr	%l5, WSTATE_KERNEL, %wstate
+	rdpr	%canrestore, %l6
+	wrpr	%l6, 0, %otherwin
+	wrpr	%g0, 0, %canrestore
+
+	sub	PCB_REG, SPOFF + CCFSZ + TF_SIZEOF, %sp
+
+	stx	%o0, [%sp + SPOFF + CCFSZ + TF_TYPE]
+	stx	%o1, [%sp + SPOFF + CCFSZ + TF_LEVEL]
+	stx	%o3, [%sp + SPOFF + CCFSZ + TF_TAR]
+	stx	%o4, [%sp + SPOFF + CCFSZ + TF_SFAR]
+	stx	%o5, [%sp + SPOFF + CCFSZ + TF_SFSR]
+
+	stx	%l0, [%sp + SPOFF + CCFSZ + TF_TSTATE]
+	stx	%l1, [%sp + SPOFF + CCFSZ + TF_TPC]
+	stx	%l2, [%sp + SPOFF + CCFSZ + TF_TNPC]
+	stx	%l3, [%sp + SPOFF + CCFSZ + TF_Y]
+	stx	%l4, [%sp + SPOFF + CCFSZ + TF_FPRS]
+	stx	%l5, [%sp + SPOFF + CCFSZ + TF_WSTATE]
+
+	wr	%g0, FPRS_FEF, %fprs
+	stx	%fsr, [%sp + SPOFF + CCFSZ + TF_FSR]
+	rd	%gsr, %l6
+	stx	%l6, [%sp + SPOFF + CCFSZ + TF_GSR]
+	wr	%g0, 0, %fprs
+
+	mov	PCB_REG, %l0
+	mov	PCPU_REG, %l1
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	stx	%g6, [%sp + SPOFF + CCFSZ + TF_G6]
+	stx	%g7, [%sp + SPOFF + CCFSZ + TF_G7]
+
+	mov	%l0, PCB_REG
+	mov	%l1, PCPU_REG
+	wrpr	%g0, PSTATE_KERNEL, %pstate
+
+	stx	%i0, [%sp + SPOFF + CCFSZ + TF_O0]
+	stx	%i1, [%sp + SPOFF + CCFSZ + TF_O1]
+	stx	%i2, [%sp + SPOFF + CCFSZ + TF_O2]
+	stx	%i3, [%sp + SPOFF + CCFSZ + TF_O3]
+	stx	%i4, [%sp + SPOFF + CCFSZ + TF_O4]
+	stx	%i5, [%sp + SPOFF + CCFSZ + TF_O5]
+	stx	%i6, [%sp + SPOFF + CCFSZ + TF_O6]
+	stx	%i7, [%sp + SPOFF + CCFSZ + TF_O7]
+
+	stx	%g1, [%sp + SPOFF + CCFSZ + TF_G1]
+	stx	%g2, [%sp + SPOFF + CCFSZ + TF_G2]
+	stx	%g3, [%sp + SPOFF + CCFSZ + TF_G3]
+	stx	%g4, [%sp + SPOFF + CCFSZ + TF_G4]
+	stx	%g5, [%sp + SPOFF + CCFSZ + TF_G5]
+
+	set	tl0_ret - 8, %o7
+	jmpl	%o2, %g0
+	 add	%sp, CCFSZ + SPOFF, %o0
+END(tl0_trap)
+
+/*
+ * void tl0_intr(u_int level, u_int mask)
+ */
+ENTRY(tl0_intr)
+	/*
+	 * Force kernel store order.
+	 */
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	rdpr	%tstate, %l0
+	rdpr	%tpc, %l1
+	rdpr	%tnpc, %l2
+	rd	%y, %l3
+	rd	%fprs, %l4
+	rdpr	%wstate, %l5
+
+#if KTR_COMPILE & KTR_INTR
+	CATR(KTR_INTR,
+	    "tl0_intr: td=%p level=%#x pil=%#lx pc=%#lx npc=%#lx sp=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	ldx	[PCPU(CURTHREAD)], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	stx	%o0, [%g1 + KTR_PARM2]
+	rdpr	%pil, %g2
+	stx	%g2, [%g1 + KTR_PARM3]
+	stx	%l1, [%g1 + KTR_PARM4]
+	stx	%l2, [%g1 + KTR_PARM5]
+	stx	%i6, [%g1 + KTR_PARM6]
+9:
+#endif
+
+	wrpr	%o0, 0, %pil
+	wr	%o1, 0, %clear_softint
+
+	and	%l5, WSTATE_NORMAL_MASK, %l5
+	sllx	%l5, WSTATE_OTHER_SHIFT, %l5
+	wrpr	%l5, WSTATE_KERNEL, %wstate
+	rdpr	%canrestore, %l6
+	wrpr	%l6, 0, %otherwin
+	wrpr	%g0, 0, %canrestore
+
+	sub	PCB_REG, SPOFF + CCFSZ + TF_SIZEOF, %sp
+
+	stx	%l0, [%sp + SPOFF + CCFSZ + TF_TSTATE]
+	stx	%l1, [%sp + SPOFF + CCFSZ + TF_TPC]
+	stx	%l2, [%sp + SPOFF + CCFSZ + TF_TNPC]
+	stx	%l3, [%sp + SPOFF + CCFSZ + TF_Y]
+	stx	%l4, [%sp + SPOFF + CCFSZ + TF_FPRS]
+	stx	%l5, [%sp + SPOFF + CCFSZ + TF_WSTATE]
+
+	wr	%g0, FPRS_FEF, %fprs
+	stx	%fsr, [%sp + SPOFF + CCFSZ + TF_FSR]
+	rd	%gsr, %l6
+	stx	%l6, [%sp + SPOFF + CCFSZ + TF_GSR]
+	wr	%g0, 0, %fprs
+
+	mov	%o0, %l3
+	mov	T_INTERRUPT, %o1
+
+	stx	%o0, [%sp + SPOFF + CCFSZ + TF_LEVEL]
+	stx	%o1, [%sp + SPOFF + CCFSZ + TF_TYPE]
+
+	mov	PCB_REG, %l0
+	mov	PCPU_REG, %l1
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	stx	%g1, [%sp + SPOFF + CCFSZ + TF_G1]
+	stx	%g2, [%sp + SPOFF + CCFSZ + TF_G2]
+	stx	%g3, [%sp + SPOFF + CCFSZ + TF_G3]
+	stx	%g4, [%sp + SPOFF + CCFSZ + TF_G4]
+	stx	%g5, [%sp + SPOFF + CCFSZ + TF_G5]
+	stx	%g6, [%sp + SPOFF + CCFSZ + TF_G6]
+	stx	%g7, [%sp + SPOFF + CCFSZ + TF_G7]
+
+	mov	%l0, PCB_REG
+	mov	%l1, PCPU_REG
+	wrpr	%g0, PSTATE_KERNEL, %pstate
+
+	stx	%i0, [%sp + SPOFF + CCFSZ + TF_O0]
+	stx	%i1, [%sp + SPOFF + CCFSZ + TF_O1]
+	stx	%i2, [%sp + SPOFF + CCFSZ + TF_O2]
+	stx	%i3, [%sp + SPOFF + CCFSZ + TF_O3]
+	stx	%i4, [%sp + SPOFF + CCFSZ + TF_O4]
+	stx	%i5, [%sp + SPOFF + CCFSZ + TF_O5]
+	stx	%i6, [%sp + SPOFF + CCFSZ + TF_O6]
+	stx	%i7, [%sp + SPOFF + CCFSZ + TF_O7]
+
+	SET(intr_handlers, %l1, %l0)
+	sllx	%l3, IH_SHIFT, %l1
+	ldx	[%l0 + %l1], %l1
+	KASSERT(%l1, "tl0_intr: ih null")
+	call	%l1
+	 add	%sp, CCFSZ + SPOFF, %o0
+
+	/* %l3 contains PIL */
+	SET(intrcnt, %l1, %l2)
+	prefetcha [%l2] ASI_N, 1
+	SET(pil_countp, %l1, %l0)
+	sllx	%l3, 1, %l1
+	lduh	[%l0 + %l1], %l0
+	sllx	%l0, 3, %l0
+	add	%l0, %l2, %l0
+	ldx	[%l0], %l1
+	inc	%l1
+	stx	%l1, [%l0]
+
+	lduw	[PCPU(CNT) + V_INTR], %l0
+	inc	%l0
+	stw	%l0, [PCPU(CNT) + V_INTR]
+
+	ba,a	%xcc, tl0_ret
+	 nop
+END(tl0_intr)
+
+/*
+ * Initiate return to usermode.
+ *
+ * Called with a trapframe on the stack.  The window that was setup in
+ * tl0_trap may have been used by "fast" trap handlers that pretend to be
+ * leaf functions, so all ins and locals may have been clobbered since
+ * then.
+ *
+ * This code is rather long and complicated.
+ */
+ENTRY(tl0_ret)
+	/*
+	 * Check for pending asts atomically with returning.  We must raise
+	 * the PIL before checking, and if no asts are found the PIL must
+	 * remain raised until the retry is executed, or we risk missing asts
+	 * caused by interrupts occurring after the test.  If the PIL is
+	 * lowered, as it is when we call ast, the check must be re-executed.
+	 */
+	wrpr	%g0, PIL_TICK, %pil
+	ldx	[PCPU(CURTHREAD)], %l0
+	lduw	[%l0 + TD_FLAGS], %l1
+	set	TDF_ASTPENDING | TDF_NEEDRESCHED, %l2
+	and	%l1, %l2, %l1
+	brz,a,pt %l1, 1f
+	 nop
+
+	/*
+	 * We have an AST.  Re-enable interrupts and handle it, then restart
+	 * the return sequence.
+	 */
+	wrpr	%g0, 0, %pil
+	call	ast
+	 add	%sp, CCFSZ + SPOFF, %o0
+	ba,a	%xcc, tl0_ret
+	 nop
+
+	/*
+	 * Check for windows that were spilled to the pcb and need to be
+	 * copied out.  This must be the last thing that is done before the
+	 * return to usermode.  If there are still user windows in the cpu
+	 * and we call a nested function after this, which causes them to be
+	 * spilled to the pcb, they will not be copied out and the stack will
+	 * be inconsistent.
+	 */
+1:	ldx	[PCB_REG + PCB_NSAVED], %l1
+	brz,a,pt %l1, 2f
+	 nop
+	wrpr	%g0, 0, %pil
+	mov	T_SPILL, %o0
+	stx	%o0, [%sp + SPOFF + CCFSZ + TF_TYPE]
+	call	trap
+	 add	%sp, SPOFF + CCFSZ, %o0
+	ba,a	%xcc, tl0_ret
+	 nop
+
+	/*
+	 * Restore the out and most global registers from the trapframe.
+	 * The ins will become the outs when we restore below.
+	 */
+2:	ldx	[%sp + SPOFF + CCFSZ + TF_O0], %i0
+	ldx	[%sp + SPOFF + CCFSZ + TF_O1], %i1
+	ldx	[%sp + SPOFF + CCFSZ + TF_O2], %i2
+	ldx	[%sp + SPOFF + CCFSZ + TF_O3], %i3
+	ldx	[%sp + SPOFF + CCFSZ + TF_O4], %i4
+	ldx	[%sp + SPOFF + CCFSZ + TF_O5], %i5
+	ldx	[%sp + SPOFF + CCFSZ + TF_O6], %i6
+	ldx	[%sp + SPOFF + CCFSZ + TF_O7], %i7
+
+	ldx	[%sp + SPOFF + CCFSZ + TF_G1], %g1
+	ldx	[%sp + SPOFF + CCFSZ + TF_G2], %g2
+	ldx	[%sp + SPOFF + CCFSZ + TF_G3], %g3
+	ldx	[%sp + SPOFF + CCFSZ + TF_G4], %g4
+	ldx	[%sp + SPOFF + CCFSZ + TF_G5], %g5
+
+	/*
+	 * Load everything we need to restore below before disabling
+	 * interrupts.
+	 */
+	ldx	[%sp + SPOFF + CCFSZ + TF_FPRS], %l0
+	ldx	[%sp + SPOFF + CCFSZ + TF_GSR], %l1
+	ldx	[%sp + SPOFF + CCFSZ + TF_TNPC], %l2
+	ldx	[%sp + SPOFF + CCFSZ + TF_TPC], %l3
+	ldx	[%sp + SPOFF + CCFSZ + TF_TSTATE], %l4
+	ldx	[%sp + SPOFF + CCFSZ + TF_Y], %l5
+	ldx	[%sp + SPOFF + CCFSZ + TF_WSTATE], %l6
+
+	/*
+	 * Disable interrupts to restore the special globals.  They are not
+	 * saved and restored for all kernel traps, so an interrupt at the
+	 * wrong time would clobber them.
+	 */
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	ldx	[%sp + SPOFF + CCFSZ + TF_G6], %g6
+	ldx	[%sp + SPOFF + CCFSZ + TF_G7], %g7
+
+	/*
+	 * Switch to alternate globals.  This frees up some registers we
+	 * can use after the restore changes our window.
+	 */
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	/*
+	 * Drop %pil to zero.  It must have been zero at the time of the
+	 * trap, since we were in usermode, but it was raised above in
+	 * order to check for asts atomically.  We have interrupts disabled
+	 * so any interrupts will not be serviced until we complete the
+	 * return to usermode.
+	 */
+	wrpr	%g0, 0, %pil
+
+	/*
+	 * Save %fprs in an alternate global so it can be restored after the
+	 * restore instruction below.  If we restore it before the restore,
+	 * and the restore traps we may run for a while with floating point
+	 * enabled in the kernel, which we want to avoid.
+	 */
+	mov	%l0, %g1
+
+	/*
+	 * Restore %fsr and %gsr.  These need floating point enabled in %fprs,
+	 * so we set it temporarily and then clear it.
+	 */
+	wr	%g0, FPRS_FEF, %fprs
+	ldx	[%sp + SPOFF + CCFSZ + TF_FSR], %fsr
+	wr	%l1, 0, %gsr
+	wr	%g0, 0, %fprs
+
+	/*
+	 * Restore program counters.  This could be done after the restore
+	 * but we're out of alternate globals to store them in...
+	 */
+	wrpr	%l2, 0, %tnpc
+	wrpr	%l3, 0, %tpc
+
+	/*
+	 * Save %tstate in an alternate global and clear the %cwp field.  %cwp
+	 * will be affected by the restore below and we need to make sure it
+	 * points to the current window at that time, not the window that was
+	 * active at the time of the trap.
+	 */
+	andn	%l4, TSTATE_CWP_MASK, %g2
+
+	/*
+	 * Restore %y.  Could also be below if we had more alternate globals.
+	 */
+	wr	%l5, 0, %y
+
+	/*
+	 * Setup %wstate for return.  We need to restore the user window state
+	 * which we saved in wstate.other when we trapped.  We also need to
+	 * set the transition bit so the restore will be handled specially
+	 * if it traps, use the xor feature of wrpr to do that.
+	 */
+	srlx	%l6, WSTATE_OTHER_SHIFT, %g3
+	wrpr	%g3, WSTATE_TRANSITION, %wstate
+
+	/*
+	 * Setup window management registers for return.  If not all user
+	 * windows were spilled in the kernel %otherwin will be non-zero,
+	 * so we need to transfer it to %canrestore to correctly restore
+	 * those windows.  Otherwise everything gets set to zero and the
+	 * restore below will fill a window directly from the user stack.
+	 */
+	rdpr	%otherwin, %o0
+	wrpr	%o0, 0, %canrestore
+	wrpr	%g0, 0, %otherwin
+	wrpr	%o0, 0, %cleanwin
+
+	/*
+	 * Now do the restore.  If this instruction causes a fill trap which
+	 * fails to fill a window from the user stack, we will resume at
+	 * tl0_ret_fill_end and call back into the kernel.
+	 */
+	restore
+tl0_ret_fill:
+
+	/*
+	 * We made it.  We're back in the window that was active at the time
+	 * of the trap, and ready to return to usermode.
+	 */
+
+	/*
+	 * Restore %frps.  This was saved in an alternate global above.
+	 */
+	wr	%g1, 0, %fprs
+
+	/*
+	 * Fixup %tstate so the saved %cwp points to the current window and
+	 * restore it.
+	 */
+	rdpr	%cwp, %g4
+	wrpr	%g2, %g4, %tstate
+
+	/*
+	 * Restore the user window state.  The transition bit was set above
+	 * for special handling of the restore, this clears it.
+	 */
+	wrpr	%g3, 0, %wstate
+
+#if KTR_COMPILE & KTR_TRAP
+	CATR(KTR_TRAP, "tl0_ret: td=%#lx pil=%#lx pc=%#lx npc=%#lx sp=%#lx"
+	    , %g2, %g3, %g4, 7, 8, 9)
+	ldx	[PCPU(CURTHREAD)], %g3
+	stx	%g3, [%g2 + KTR_PARM1]
+	rdpr	%pil, %g3
+	stx	%g3, [%g2 + KTR_PARM2]
+	rdpr	%tpc, %g3
+	stx	%g3, [%g2 + KTR_PARM3]
+	rdpr	%tnpc, %g3
+	stx	%g3, [%g2 + KTR_PARM4]
+	stx	%sp, [%g2 + KTR_PARM5]
+9:
+#endif
+
+	/*
+	 * Return to usermode.
+	 */
+	retry
+tl0_ret_fill_end:
+
+#if KTR_COMPILE & KTR_TRAP
+	CATR(KTR_TRAP, "tl0_ret: fill magic ps=%#lx ws=%#lx sp=%#lx"
+	    , %l0, %l1, %l2, 7, 8, 9)
+	rdpr	%pstate, %l1
+	stx	%l1, [%l0 + KTR_PARM1]
+	stx	%l6, [%l0 + KTR_PARM2]
+	stx	%sp, [%l0 + KTR_PARM3]
+9:
+#endif
+
+	/*
+	 * The restore above caused a fill trap and the fill handler was
+	 * unable to fill a window from the user stack.  The special fill
+	 * handler recognized this and punted, sending us here.  We need
+	 * to carefully undo any state that was restored before the restore
+	 * was executed and call trap again.  Trap will copyin a window
+	 * from the user stack which will fault in the page we need so the
+	 * restore above will succeed when we try again.  If this fails
+	 * the process has trashed its stack, so we kill it.
+	 */
+
+	/*
+	 * Restore the kernel window state.  This was saved in %l6 above, and
+	 * since the restore failed we're back in the same window.
+	 */
+	wrpr	%l6, 0, %wstate
+
+	/*
+	 * Restore the normal globals which have predefined values in the
+	 * kernel.  We clobbered them above restoring the user's globals
+	 * so this is very important.
+	 * XXX PSTATE_ALT must already be set.
+	 */
+	wrpr	%g0, PSTATE_ALT, %pstate
+	mov	PCB_REG, %o0
+	mov	PCPU_REG, %o1
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+	mov	%o0, PCB_REG
+	mov	%o1, PCPU_REG
+	wrpr	%g0, PSTATE_KERNEL, %pstate
+
+	/*
+	 * Simulate a fill trap and then start the whole return sequence over
+	 * again.  This is special because it only copies in 1 window, not 2
+	 * as we would for a normal failed fill.  This may be the first time
+	 * the process has been run, so there may not be 2 windows worth of
+	 * stack to copyin.
+	 */
+	mov	T_FILL_RET, %o0
+	stx	%o0, [%sp + SPOFF + CCFSZ + TF_TYPE]
+	call	trap
+	 add	%sp, SPOFF + CCFSZ, %o0
+	ba,a	%xcc, tl0_ret
+	 nop
+END(tl0_ret)
+
+/*
+ * Kernel trap entry point
+ *
+ * void tl1_trap(u_int type, u_long o1, u_long o2, u_long tar, u_long sfar,
+ *     u_int sfsr)
+ *
+ * This is easy because the stack is already setup and the windows don't need
+ * to be split.  We build a trapframe and call trap(), the same as above, but
+ * the outs don't need to be saved.
+ */
+ENTRY(tl1_trap)
+	rdpr	%tstate, %l0
+	rdpr	%tpc, %l1
+	rdpr	%tnpc, %l2
+	rdpr	%pil, %l3
+	rd	%y, %l4
+	rdpr	%wstate, %l5
+
+#if KTR_COMPILE & KTR_TRAP
+	CATR(KTR_TRAP, "tl1_trap: td=%p type=%#lx pil=%#lx pc=%#lx sp=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	ldx	[PCPU(CURTHREAD)], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	stx	%o0, [%g1 + KTR_PARM2]
+	stx	%l3, [%g1 + KTR_PARM3]
+	stx	%l1, [%g1 + KTR_PARM4]
+	stx	%i6, [%g1 + KTR_PARM5]
+9:
+#endif
+
+	wrpr	%g0, 1, %tl
+
+	and	%l5, WSTATE_OTHER_MASK, %l5
+	wrpr	%l5, WSTATE_KERNEL, %wstate
+
+	stx	%o0, [%sp + SPOFF + CCFSZ + TF_TYPE]
+	stx	%o1, [%sp + SPOFF + CCFSZ + TF_LEVEL]
+	stx	%o3, [%sp + SPOFF + CCFSZ + TF_TAR]
+	stx	%o4, [%sp + SPOFF + CCFSZ + TF_SFAR]
+	stx	%o5, [%sp + SPOFF + CCFSZ + TF_SFSR]
+
+	stx	%l0, [%sp + SPOFF + CCFSZ + TF_TSTATE]
+	stx	%l1, [%sp + SPOFF + CCFSZ + TF_TPC]
+	stx	%l2, [%sp + SPOFF + CCFSZ + TF_TNPC]
+	stx	%l3, [%sp + SPOFF + CCFSZ + TF_PIL]
+	stx	%l4, [%sp + SPOFF + CCFSZ + TF_Y]
+
+	mov	PCB_REG, %l0
+	mov	PCPU_REG, %l1
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	stx	%g6, [%sp + SPOFF + CCFSZ + TF_G6]
+	stx	%g7, [%sp + SPOFF + CCFSZ + TF_G7]
+
+	mov	%l0, PCB_REG
+	mov	%l1, PCPU_REG
+	wrpr	%g0, PSTATE_KERNEL, %pstate
+
+	stx	%i0, [%sp + SPOFF + CCFSZ + TF_O0]
+	stx	%i1, [%sp + SPOFF + CCFSZ + TF_O1]
+	stx	%i2, [%sp + SPOFF + CCFSZ + TF_O2]
+	stx	%i3, [%sp + SPOFF + CCFSZ + TF_O3]
+	stx	%i4, [%sp + SPOFF + CCFSZ + TF_O4]
+	stx	%i5, [%sp + SPOFF + CCFSZ + TF_O5]
+	stx	%i6, [%sp + SPOFF + CCFSZ + TF_O6]
+	stx	%i7, [%sp + SPOFF + CCFSZ + TF_O7]
+
+	stx	%g1, [%sp + SPOFF + CCFSZ + TF_G1]
+	stx	%g2, [%sp + SPOFF + CCFSZ + TF_G2]
+	stx	%g3, [%sp + SPOFF + CCFSZ + TF_G3]
+	stx	%g4, [%sp + SPOFF + CCFSZ + TF_G4]
+	stx	%g5, [%sp + SPOFF + CCFSZ + TF_G5]
+
+	set	tl1_ret - 8, %o7
+	jmpl	%o2, %g0
+	 add	%sp, CCFSZ + SPOFF, %o0
+END(tl1_trap)
+
+ENTRY(tl1_ret)
+	ldx	[%sp + SPOFF + CCFSZ + TF_O0], %i0
+	ldx	[%sp + SPOFF + CCFSZ + TF_O1], %i1
+	ldx	[%sp + SPOFF + CCFSZ + TF_O2], %i2
+	ldx	[%sp + SPOFF + CCFSZ + TF_O3], %i3
+	ldx	[%sp + SPOFF + CCFSZ + TF_O4], %i4
+	ldx	[%sp + SPOFF + CCFSZ + TF_O5], %i5
+	ldx	[%sp + SPOFF + CCFSZ + TF_O6], %i6
+	ldx	[%sp + SPOFF + CCFSZ + TF_O7], %i7
+
+	ldx	[%sp + SPOFF + CCFSZ + TF_G1], %g1
+	ldx	[%sp + SPOFF + CCFSZ + TF_G2], %g2
+	ldx	[%sp + SPOFF + CCFSZ + TF_G3], %g3
+	ldx	[%sp + SPOFF + CCFSZ + TF_G4], %g4
+	ldx	[%sp + SPOFF + CCFSZ + TF_G5], %g5
+
+	ldx	[%sp + SPOFF + CCFSZ + TF_TSTATE], %l0
+	ldx	[%sp + SPOFF + CCFSZ + TF_TPC], %l1
+	ldx	[%sp + SPOFF + CCFSZ + TF_TNPC], %l2
+	ldx	[%sp + SPOFF + CCFSZ + TF_PIL], %l3
+	ldx	[%sp + SPOFF + CCFSZ + TF_Y], %l4
+
+	set	VM_MIN_PROM_ADDRESS, %l5
+	cmp	%l1, %l5
+	bl,a,pt	%xcc, 1f
+	 nop
+	set	VM_MAX_PROM_ADDRESS, %l5
+	cmp	%l1, %l5
+	bg,a,pt	%xcc, 1f
+	 nop
+
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	ldx	[%sp + SPOFF + CCFSZ + TF_G6], %g6
+	ldx	[%sp + SPOFF + CCFSZ + TF_G7], %g7
+
+1:	wrpr	%g0, PSTATE_ALT, %pstate
+
+	andn	%l0, TSTATE_CWP_MASK, %g1
+	mov	%l1, %g2
+	mov	%l2, %g3
+
+	wrpr	%l3, 0, %pil
+	wr	%l4, 0, %y
+
+	restore
+
+	wrpr	%g0, 2, %tl
+
+	rdpr	%cwp, %g4
+	wrpr	%g1, %g4, %tstate
+	wrpr	%g2, 0, %tpc
+	wrpr	%g3, 0, %tnpc
+
+#if KTR_COMPILE & KTR_TRAP
+	CATR(KTR_TRAP, "tl1_ret: td=%#lx pil=%#lx ts=%#lx pc=%#lx sp=%#lx"
+	    , %g2, %g3, %g4, 7, 8, 9)
+	ldx	[PCPU(CURTHREAD)], %g3
+	stx	%g3, [%g2 + KTR_PARM1]
+	rdpr	%pil, %g3
+	stx	%g3, [%g2 + KTR_PARM2]
+	rdpr	%tstate, %g3
+	stx	%g3, [%g2 + KTR_PARM3]
+	rdpr	%tpc, %g3
+	stx	%g3, [%g2 + KTR_PARM4]
+	stx	%sp, [%g2 + KTR_PARM5]
+9:
+#endif
+
+	retry
+END(tl1_ret)
+
+/*
+ * void tl1_intr(u_int level, u_int mask)
+ */
+ENTRY(tl1_intr)
+	rdpr	%tstate, %l0
+	rdpr	%tpc, %l1
+	rdpr	%tnpc, %l2
+	rdpr	%pil, %l3
+	rd	%y, %l4
+	rdpr	%wstate, %l5
+
+#if KTR_COMPILE & KTR_INTR
+	CATR(KTR_INTR,
+	    "tl1_intr: td=%p level=%#x pil=%#lx pc=%#lx sp=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	ldx	[PCPU(CURTHREAD)], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	stx	%o0, [%g1 + KTR_PARM2]
+	stx	%l3, [%g1 + KTR_PARM3]
+	stx	%l1, [%g1 + KTR_PARM4]
+	stx	%i6, [%g1 + KTR_PARM5]
+9:
+#endif
+
+	wrpr	%o0, 0, %pil
+	wr	%o1, 0, %clear_softint
+
+	wrpr	%g0, 1, %tl
+
+	and	%l5, WSTATE_OTHER_MASK, %l5
+	wrpr	%l5, WSTATE_KERNEL, %wstate
+
+	stx	%l0, [%sp + SPOFF + CCFSZ + TF_TSTATE]
+	stx	%l1, [%sp + SPOFF + CCFSZ + TF_TPC]
+	stx	%l2, [%sp + SPOFF + CCFSZ + TF_TNPC]
+	stx	%l3, [%sp + SPOFF + CCFSZ + TF_PIL]
+	stx	%l4, [%sp + SPOFF + CCFSZ + TF_Y]
+
+	mov	%o0, %l7
+	mov	T_INTERRUPT | T_KERNEL, %o1
+
+	stx	%o0, [%sp + SPOFF + CCFSZ + TF_LEVEL]
+	stx	%o1, [%sp + SPOFF + CCFSZ + TF_TYPE]
+
+	stx	%i6, [%sp + SPOFF + CCFSZ + TF_O6]
+	stx	%i7, [%sp + SPOFF + CCFSZ + TF_O7]
+
+	mov	PCB_REG, %l4
+	mov	PCPU_REG, %l5
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	stx	%g1, [%sp + SPOFF + CCFSZ + TF_G1]
+	stx	%g2, [%sp + SPOFF + CCFSZ + TF_G2]
+	stx	%g3, [%sp + SPOFF + CCFSZ + TF_G3]
+	stx	%g4, [%sp + SPOFF + CCFSZ + TF_G4]
+	stx	%g5, [%sp + SPOFF + CCFSZ + TF_G5]
+
+	mov	%l4, PCB_REG
+	mov	%l5, PCPU_REG
+	wrpr	%g0, PSTATE_KERNEL, %pstate
+
+	SET(intr_handlers, %l5, %l4)
+	sllx	%l7, IH_SHIFT, %l5
+	ldx	[%l4 + %l5], %l5
+	KASSERT(%l5, "tl1_intr: ih null")
+	call	%l5
+	 add	%sp, CCFSZ + SPOFF, %o0
+
+	/* %l7 contains PIL */
+	SET(intrcnt, %l5, %l4)
+	prefetcha [%l4] ASI_N, 1
+	SET(pil_countp, %l5, %l6)
+	sllx	%l7, 1, %l5
+	lduh	[%l5 + %l6], %l5
+	sllx	%l5, 3, %l5
+	add	%l5, %l4, %l4
+	ldx	[%l4], %l5
+	inc	%l5
+	stx	%l5, [%l4]
+
+	lduw	[PCPU(CNT) + V_INTR], %l4
+	inc	%l4
+	stw	%l4, [PCPU(CNT) + V_INTR]
+
+	ldx	[%sp + SPOFF + CCFSZ + TF_Y], %l4
+
+	ldx	[%sp + SPOFF + CCFSZ + TF_G1], %g1
+	ldx	[%sp + SPOFF + CCFSZ + TF_G2], %g2
+	ldx	[%sp + SPOFF + CCFSZ + TF_G3], %g3
+	ldx	[%sp + SPOFF + CCFSZ + TF_G4], %g4
+	ldx	[%sp + SPOFF + CCFSZ + TF_G5], %g5
+
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	andn	%l0, TSTATE_CWP_MASK, %g1
+	mov	%l1, %g2
+	mov	%l2, %g3
+	wrpr	%l3, 0, %pil
+	wr	%l4, 0, %y
+
+	restore
+
+	wrpr	%g0, 2, %tl
+
+	rdpr	%cwp, %g4
+	wrpr	%g1, %g4, %tstate
+	wrpr	%g2, 0, %tpc
+	wrpr	%g3, 0, %tnpc
+
+#if KTR_COMPILE & KTR_INTR
+	CATR(KTR_INTR, "tl1_intr: td=%#x pil=%#lx ts=%#lx pc=%#lx sp=%#lx"
+	    , %g2, %g3, %g4, 7, 8, 9)
+	ldx	[PCPU(CURTHREAD)], %g3
+	stx	%g3, [%g2 + KTR_PARM1]
+	rdpr	%pil, %g3
+	stx	%g3, [%g2 + KTR_PARM2]
+	rdpr	%tstate, %g3
+	stx	%g3, [%g2 + KTR_PARM3]
+	rdpr	%tpc, %g3
+	stx	%g3, [%g2 + KTR_PARM4]
+	stx	%sp, [%g2 + KTR_PARM5]
+9:
+#endif
+
+	retry
+END(tl1_intr)
+
+	.globl	tl_text_end
+tl_text_end:
+	nop
+
+/*
+ * Freshly forked processes come here when switched to for the first time.
+ * The arguments to fork_exit() have been setup in the locals, we must move
+ * them to the outs.
+ */
+ENTRY(fork_trampoline)
+#if KTR_COMPILE & KTR_PROC
+	CATR(KTR_PROC, "fork_trampoline: td=%p (%s) cwp=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	ldx	[PCPU(CURTHREAD)], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	ldx	[%g2 + TD_PROC], %g2
+	add	%g2, P_COMM, %g2
+	stx	%g2, [%g1 + KTR_PARM2]
+	rdpr	%cwp, %g2
+	stx	%g2, [%g1 + KTR_PARM3]
+9:
+#endif
+	mov	%l0, %o0
+	mov	%l1, %o1
+	call	fork_exit
+	 mov	%l2, %o2
+	ba,a	%xcc, tl0_ret
+	 nop
+END(fork_trampoline)


Property changes on: trunk/sys/sparc64/sparc64/exception.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/gdb_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/gdb_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/gdb_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,71 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Marcel Moolenaar
+ * 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 AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/gdb_machdep.c 139825 2005-01-07 02:29:27Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/signal.h>
+
+#include <machine/asm.h>
+#include <machine/gdb_machdep.h>
+#include <machine/pcb.h>
+#include <machine/reg.h>
+
+#include <gdb/gdb.h>
+
+void *
+gdb_cpu_getreg(int regnum, size_t *regsz)
+{
+	static uint64_t synth;
+
+	*regsz = gdb_cpu_regsz(regnum);
+	switch (regnum) {
+		/* 0-7: g0-g7 */
+		/* 8-15: o0-o7 */
+	case 14:
+		synth = kdb_thrctx->pcb_sp - CCFSZ;
+		return (&synth);
+		/* 16-23: l0-l7 */
+		/* 24-31: i0-i7 */
+	case 30: return (&kdb_thrctx->pcb_sp);
+		/* 32-63: f0-f31 */
+		/* 64-79: f32-f62 (16 double FP) */	
+	case 80: return (&kdb_thrctx->pcb_pc);
+	}
+	return (NULL);
+}
+
+void
+gdb_cpu_setreg(int regnum, void *val)
+{
+	switch (regnum) {
+	}
+}


Property changes on: trunk/sys/sparc64/sparc64/gdb_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/genassym.c
===================================================================
--- trunk/sys/sparc64/sparc64/genassym.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/genassym.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,246 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ *	from: @(#)genassym.c	5.11 (Berkeley) 5/10/91
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/genassym.c 254065 2013-08-07 16:36:38Z kib $");
+
+#include "opt_kstack_pages.h"
+
+#include <sys/param.h>
+#include <sys/assym.h>
+#include <sys/ktr.h>
+#include <sys/proc.h>
+#include <sys/smp.h>
+#include <sys/vmmeter.h>
+#include <sys/_cpuset.h>
+
+#include <machine/atomic.h>
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+
+#include <machine/cache.h>
+#include <machine/pcb.h>
+#include <machine/setjmp.h>
+#include <machine/smp.h>
+#include <machine/tlb.h>
+#include <machine/tte.h>
+#include <machine/vmparam.h>
+
+ASSYM(KERNBASE, KERNBASE);
+
+ASSYM(KSTACK_PAGES, KSTACK_PAGES);
+ASSYM(PCPU_PAGES, PCPU_PAGES);
+
+ASSYM(TAR_VPN_SHIFT, TAR_VPN_SHIFT);
+
+ASSYM(_NCPUBITS, _NCPUBITS);
+
+ASSYM(TLB_DEMAP_ALL, TLB_DEMAP_ALL);
+ASSYM(TLB_DEMAP_CONTEXT, TLB_DEMAP_CONTEXT);
+ASSYM(TLB_DEMAP_NUCLEUS, TLB_DEMAP_NUCLEUS);
+ASSYM(TLB_DEMAP_PAGE, TLB_DEMAP_PAGE);
+ASSYM(TLB_DEMAP_PRIMARY, TLB_DEMAP_PRIMARY);
+
+ASSYM(INT_SHIFT, INT_SHIFT);
+ASSYM(PTR_SHIFT, PTR_SHIFT);
+
+ASSYM(PAGE_SHIFT, PAGE_SHIFT);
+ASSYM(PAGE_SHIFT_8K, PAGE_SHIFT_8K);
+ASSYM(PAGE_SHIFT_4M, PAGE_SHIFT_4M);
+ASSYM(PAGE_SIZE, PAGE_SIZE);
+ASSYM(PAGE_SIZE_4M, PAGE_SIZE_4M);
+
+#ifdef SMP
+ASSYM(CSA_PCPU, offsetof(struct cpu_start_args, csa_pcpu));
+ASSYM(CSA_STATE, offsetof(struct cpu_start_args, csa_state));
+ASSYM(CSA_MID, offsetof(struct cpu_start_args, csa_mid));
+ASSYM(CSA_STICK, offsetof(struct cpu_start_args, csa_stick));
+ASSYM(CSA_TICK, offsetof(struct cpu_start_args, csa_tick));
+ASSYM(CSA_TTES, offsetof(struct cpu_start_args, csa_ttes));
+ASSYM(CSA_VER, offsetof(struct cpu_start_args, csa_ver));
+#endif
+
+ASSYM(DC_SIZE, offsetof(struct cacheinfo, dc_size));
+ASSYM(DC_LINESIZE, offsetof(struct cacheinfo, dc_linesize));
+ASSYM(IC_SIZE, offsetof(struct cacheinfo, ic_size));
+ASSYM(IC_LINESIZE, offsetof(struct cacheinfo, ic_linesize));
+
+ASSYM(KTR_SIZEOF, sizeof(struct ktr_entry));
+ASSYM(KTR_LINE, offsetof(struct ktr_entry, ktr_line));
+ASSYM(KTR_FILE, offsetof(struct ktr_entry, ktr_file));
+ASSYM(KTR_DESC, offsetof(struct ktr_entry, ktr_desc));
+ASSYM(KTR_CPU, offsetof(struct ktr_entry, ktr_cpu));
+ASSYM(KTR_TIMESTAMP, offsetof(struct ktr_entry, ktr_timestamp));
+ASSYM(KTR_PARM1, offsetof(struct ktr_entry, ktr_parms[0]));
+ASSYM(KTR_PARM2, offsetof(struct ktr_entry, ktr_parms[1]));
+ASSYM(KTR_PARM3, offsetof(struct ktr_entry, ktr_parms[2]));
+ASSYM(KTR_PARM4, offsetof(struct ktr_entry, ktr_parms[3]));
+ASSYM(KTR_PARM5, offsetof(struct ktr_entry, ktr_parms[4]));
+ASSYM(KTR_PARM6, offsetof(struct ktr_entry, ktr_parms[5]));
+
+ASSYM(TTE_SHIFT, TTE_SHIFT);
+ASSYM(TTE_VPN, offsetof(struct tte, tte_vpn));
+ASSYM(TTE_DATA, offsetof(struct tte, tte_data));
+
+ASSYM(TD_V, TD_V);
+ASSYM(TD_EXEC, TD_EXEC);
+ASSYM(TD_REF, TD_REF);
+ASSYM(TD_SW, TD_SW);
+ASSYM(TD_L, TD_L);
+ASSYM(TD_CP, TD_CP);
+ASSYM(TD_CV, TD_CV);
+ASSYM(TD_W, TD_W);
+
+ASSYM(TS_MIN, TS_MIN);
+ASSYM(TS_MAX, TS_MAX);
+ASSYM(TLB_DAR_SLOT_SHIFT, TLB_DAR_SLOT_SHIFT);
+ASSYM(TLB_CXR_PGSZ_MASK, TLB_CXR_PGSZ_MASK);
+ASSYM(TLB_DIRECT_ADDRESS_MASK, TLB_DIRECT_ADDRESS_MASK);
+ASSYM(TLB_DIRECT_TO_TTE_MASK, TLB_DIRECT_TO_TTE_MASK);
+ASSYM(TV_SIZE_BITS, TV_SIZE_BITS);
+
+ASSYM(V_INTR, offsetof(struct vmmeter, v_intr));
+
+ASSYM(MAXCOMLEN, MAXCOMLEN);
+ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
+ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
+ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid));
+ASSYM(PC_IRHEAD, offsetof(struct pcpu, pc_irhead));
+ASSYM(PC_IRTAIL, offsetof(struct pcpu, pc_irtail));
+ASSYM(PC_IRFREE, offsetof(struct pcpu, pc_irfree));
+ASSYM(PC_CNT, offsetof(struct pcpu, pc_cnt));
+ASSYM(PC_SIZEOF, sizeof(struct pcpu));
+
+ASSYM(PC_CACHE, offsetof(struct pcpu, pc_cache));
+ASSYM(PC_MID, offsetof(struct pcpu, pc_mid));
+ASSYM(PC_PMAP, offsetof(struct pcpu, pc_pmap));
+ASSYM(PC_TLB_CTX, offsetof(struct pcpu, pc_tlb_ctx));
+ASSYM(PC_TLB_CTX_MAX, offsetof(struct pcpu, pc_tlb_ctx_max));
+ASSYM(PC_TLB_CTX_MIN, offsetof(struct pcpu, pc_tlb_ctx_min));
+
+ASSYM(IR_NEXT, offsetof(struct intr_request, ir_next));
+ASSYM(IR_FUNC, offsetof(struct intr_request, ir_func));
+ASSYM(IR_ARG, offsetof(struct intr_request, ir_arg));
+ASSYM(IR_PRI, offsetof(struct intr_request, ir_pri));
+ASSYM(IR_VEC, offsetof(struct intr_request, ir_vec));
+
+#ifdef SMP
+ASSYM(ICA_PA, offsetof(struct ipi_cache_args, ica_pa));
+
+ASSYM(IRA_MASK, offsetof(struct ipi_rd_args, ira_mask));
+ASSYM(IRA_VAL, offsetof(struct ipi_rd_args, ira_val));
+
+ASSYM(ITA_MASK, offsetof(struct ipi_tlb_args, ita_mask));
+ASSYM(ITA_PMAP, offsetof(struct ipi_tlb_args, ita_pmap));
+ASSYM(ITA_START, offsetof(struct ipi_tlb_args, ita_start));
+ASSYM(ITA_END, offsetof(struct ipi_tlb_args, ita_end));
+ASSYM(ITA_VA, offsetof(struct ipi_tlb_args, ita_va));
+#endif
+
+ASSYM(IV_FUNC, offsetof(struct intr_vector, iv_func));
+ASSYM(IV_ARG, offsetof(struct intr_vector, iv_arg));
+ASSYM(IV_PRI, offsetof(struct intr_vector, iv_pri));
+
+ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
+ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
+
+ASSYM(MD_UTRAP, offsetof(struct mdproc, md_utrap));
+
+ASSYM(P_COMM, offsetof(struct proc, p_comm));
+ASSYM(P_MD, offsetof(struct proc, p_md));
+ASSYM(P_PID, offsetof(struct proc, p_pid));
+ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
+
+ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
+ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
+ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack));
+ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
+ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
+ASSYM(TD_PROC, offsetof(struct thread, td_proc));
+ASSYM(TD_MD, offsetof(struct thread, td_md));
+ASSYM(MD_SAVED_PIL, offsetof(struct mdthread, md_saved_pil));
+
+ASSYM(PCB_SIZEOF, sizeof(struct pcb));
+ASSYM(PCB_RW, offsetof(struct pcb, pcb_rw));
+ASSYM(PCB_KFP, offsetof(struct pcb, pcb_kfp));
+ASSYM(PCB_UFP, offsetof(struct pcb, pcb_ufp));
+ASSYM(PCB_RWSP, offsetof(struct pcb, pcb_rwsp));
+ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
+ASSYM(PCB_NSAVED, offsetof(struct pcb, pcb_nsaved));
+ASSYM(PCB_PC, offsetof(struct pcb, pcb_pc));
+ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp));
+ASSYM(PCB_PAD, offsetof(struct pcb, pcb_pad));
+
+ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap));
+ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active));
+ASSYM(PM_CONTEXT, offsetof(struct pmap, pm_context));
+ASSYM(PM_TSB, offsetof(struct pmap, pm_tsb));
+
+ASSYM(_JB_FP, offsetof(struct _jmp_buf, _jb[_JB_FP]));
+ASSYM(_JB_PC, offsetof(struct _jmp_buf, _jb[_JB_PC]));
+ASSYM(_JB_SP, offsetof(struct _jmp_buf, _jb[_JB_SP]));
+ASSYM(_JB_SIGFLAG, offsetof(struct _jmp_buf, _jb[_JB_SIGFLAG]));
+ASSYM(_JB_SIGMASK, offsetof(struct _jmp_buf, _jb[_JB_SIGMASK]));
+
+ASSYM(TF_G0, offsetof(struct trapframe, tf_global[0]));
+ASSYM(TF_G1, offsetof(struct trapframe, tf_global[1]));
+ASSYM(TF_G2, offsetof(struct trapframe, tf_global[2]));
+ASSYM(TF_G3, offsetof(struct trapframe, tf_global[3]));
+ASSYM(TF_G4, offsetof(struct trapframe, tf_global[4]));
+ASSYM(TF_G5, offsetof(struct trapframe, tf_global[5]));
+ASSYM(TF_G6, offsetof(struct trapframe, tf_global[6]));
+ASSYM(TF_G7, offsetof(struct trapframe, tf_global[7]));
+ASSYM(TF_O0, offsetof(struct trapframe, tf_out[0]));
+ASSYM(TF_O1, offsetof(struct trapframe, tf_out[1]));
+ASSYM(TF_O2, offsetof(struct trapframe, tf_out[2]));
+ASSYM(TF_O3, offsetof(struct trapframe, tf_out[3]));
+ASSYM(TF_O4, offsetof(struct trapframe, tf_out[4]));
+ASSYM(TF_O5, offsetof(struct trapframe, tf_out[5]));
+ASSYM(TF_O6, offsetof(struct trapframe, tf_out[6]));
+ASSYM(TF_O7, offsetof(struct trapframe, tf_out[7]));
+ASSYM(TF_FPRS, offsetof(struct trapframe, tf_fprs));
+ASSYM(TF_FSR, offsetof(struct trapframe, tf_fsr));
+ASSYM(TF_GSR, offsetof(struct trapframe, tf_gsr));
+ASSYM(TF_PIL, offsetof(struct trapframe, tf_pil));
+ASSYM(TF_LEVEL, offsetof(struct trapframe, tf_level));
+ASSYM(TF_SFAR, offsetof(struct trapframe, tf_sfar));
+ASSYM(TF_SFSR, offsetof(struct trapframe, tf_sfsr));
+ASSYM(TF_TAR, offsetof(struct trapframe, tf_tar));
+ASSYM(TF_TYPE, offsetof(struct trapframe, tf_type));
+ASSYM(TF_Y, offsetof(struct trapframe, tf_y));
+ASSYM(TF_TNPC, offsetof(struct trapframe, tf_tnpc));
+ASSYM(TF_TPC, offsetof(struct trapframe, tf_tpc));
+ASSYM(TF_TSTATE, offsetof(struct trapframe, tf_tstate));
+ASSYM(TF_WSTATE, offsetof(struct trapframe, tf_wstate));
+ASSYM(TF_SIZEOF, sizeof(struct trapframe));
+
+ASSYM(VM_MIN_DIRECT_ADDRESS, VM_MIN_DIRECT_ADDRESS);
+ASSYM(VM_MIN_PROM_ADDRESS, VM_MIN_PROM_ADDRESS);
+ASSYM(VM_MAX_PROM_ADDRESS, VM_MAX_PROM_ADDRESS);


Property changes on: trunk/sys/sparc64/sparc64/genassym.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/identcpu.c
===================================================================
--- trunk/sys/sparc64/sparc64/identcpu.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/identcpu.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,139 @@
+/* $MidnightBSD$ */
+/*-
+ * Initial implementation:
+ * Copyright (c) 2001 Robert Drehmel
+ * All rights reserved.
+ *
+ * As long as the above copyright statement and this notice remain
+ * unchanged, you can do what ever you want with this file.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/identcpu.c 227309 2011-11-07 15:43:11Z ed $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+
+#include <machine/md_var.h>
+#include <machine/ver.h>
+
+char machine[] = MACHINE;
+SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
+    machine, 0, "Machine class");
+
+static char cpu_model[128];
+SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD,
+    cpu_model, 0, "Machine model");
+
+static SYSCTL_NODE(_hw, OID_AUTO, freq, CTLFLAG_RD, 0, "");
+
+static u_int cpu_count;
+static u_int cpu_freq;
+SYSCTL_UINT(_hw_freq, OID_AUTO, cpu, CTLFLAG_RD, &cpu_freq, 0,
+    "CPU clock frequency");
+
+void
+cpu_identify(u_long vers, u_int freq, u_int id)
+{
+	const char *manus;
+	const char *impls;
+
+	switch (VER_MANUF(vers)) {
+	case 0x04:
+		manus = "HAL/Fujitsu";
+		break;
+	case 0x13:
+	case 0x17:
+	case 0x22:
+	case 0x3e:
+		manus = "Sun Microsystems";
+		break;
+	default:
+		manus = NULL;
+		break;
+	}
+	switch (VER_IMPL(vers)) {
+	case CPU_IMPL_SPARC64:
+		impls = "SPARC64";
+		break;
+	case CPU_IMPL_SPARC64II:
+		impls = "SPARC64-II";
+		break;
+	case CPU_IMPL_SPARC64III:
+		impls = "SPARC64-III";
+		break;
+	case CPU_IMPL_SPARC64IV:
+		impls = "SPARC64-IV";
+		break;
+	case CPU_IMPL_SPARC64V:
+		impls = "SPARC64-V";
+		break;
+	case CPU_IMPL_SPARC64VI:
+		impls = "SPARC64-VI";
+		break;
+	case CPU_IMPL_SPARC64VII:
+		impls = "SPARC64-VII";
+		break;
+	case CPU_IMPL_SPARC64VIIIfx:
+		impls = "SPARC64-VIIIfx";
+		break;
+	case CPU_IMPL_ULTRASPARCI:
+		impls = "UltraSparc-I";
+		break;
+	case CPU_IMPL_ULTRASPARCII:
+		impls = "UltraSparc-II";
+		break;
+	case CPU_IMPL_ULTRASPARCIIi:
+		impls = "UltraSparc-IIi";
+		break;
+	case CPU_IMPL_ULTRASPARCIIe:
+		impls = "UltraSparc-IIe";
+		break;
+	case CPU_IMPL_ULTRASPARCIII:
+		impls = "UltraSparc-III";
+		break;
+	case CPU_IMPL_ULTRASPARCIIIp:
+		impls = "UltraSparc-III+";
+		break;
+	case CPU_IMPL_ULTRASPARCIIIi:
+		impls = "UltraSparc-IIIi";
+		break;
+	case CPU_IMPL_ULTRASPARCIV:
+		impls = "UltraSparc-IV";
+		break;
+	case CPU_IMPL_ULTRASPARCIVp:
+		impls = "UltraSparc-IV+";
+		break;
+	case CPU_IMPL_ULTRASPARCIIIip:
+		impls = "UltraSparc-IIIi+";
+		break;
+	default:
+		impls = NULL;
+		break;
+	}
+	if (manus == NULL || impls == NULL) {
+		printf(
+		    "CPU: unknown; please e-mail the following value together\n"
+		    "     with the exact name of your processor to "
+		    "<freebsd-sparc64 at FreeBSD.org>.\n"
+		    "     version register: <0x%lx>\n", vers);
+		return;
+	}
+
+	snprintf(cpu_model, sizeof(cpu_model), "%s %s", manus, impls);
+	printf("cpu%d: %s %s Processor (%d.%02d MHz CPU)\n", id, manus, impls,
+	    (freq + 4999) / 1000000, ((freq + 4999) / 10000) % 100);
+	if (bootverbose) {
+		printf("  mask=0x%lx maxtl=%ld maxwin=%ld\n", VER_MASK(vers),
+		    VER_MAXTL(vers), VER_MAXWIN(vers));
+	}
+
+	/*
+	 * Calculate the average CPU frequency.
+	 */
+	freq = (freq + 500000ul) / 1000000ul;
+	cpu_freq = (cpu_freq * cpu_count + freq) / (cpu_count + 1);
+	cpu_count++;
+}


Property changes on: trunk/sys/sparc64/sparc64/identcpu.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/in_cksum.c
===================================================================
--- trunk/sys/sparc64/sparc64/in_cksum.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/in_cksum.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,263 @@
+/* $MidnightBSD$ */
+/*-
+ * 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.
+ * 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.
+ */
+/*-
+ * Copyright (c) 2001 by Thomas Moestl <tmm at 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, 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 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: FreeBSD: src/sys/i386/i386/in_cksum.c,v 1.22 2000/11/25
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/in_cksum.c 180299 2008-07-05 15:44:56Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <machine/in_cksum.h>
+
+/*
+ * Checksum routine for Internet Protocol family headers.
+ *
+ * This routine is very heavily used in the network
+ * code and should be modified for each CPU to be as fast as possible.
+ *
+ * This implementation is a sparc64 version.  Most code was taken over
+ * and adapted from the i386.  Some optimizations were changed to achieve
+ * (hopefully) better performance.
+ * This uses 64-bit loads, but 32-bit additions due to the lack of a 64-bit
+ * add-with-carry operation.
+ */
+
+/*
+ * REDUCE() is actually not used that frequently... maybe a C implementation
+ * would suffice.
+ */
+#define	REDUCE(sum, tmp) __asm(						\
+	"sll %2, 16, %1\n"						\
+	"addcc %2, %1, %0\n"						\
+	"srl %0, 16, %0\n"						\
+	"addc %0, 0, %0" : "=r" (sum), "=&r" (tmp) : "0" (sum) : "cc")
+
+/*
+ * Note that some of these macros depend on the flags being preserved
+ * between calls, thus they have to be used within a single __asm().
+ */
+#define	LD64_ADD32(n, mod)						\
+	"ldx [%3 + " #n "], %1\n"					\
+	"add" #mod " %2, %1, %0\n"					\
+	"srlx %1, 32, %1\n"						\
+	"addccc %0, %1, %0\n"
+
+#define	LD32_ADD32(n, mod)						\
+	"lduw [%3 + " #n "], %1\n"					\
+	"add" #mod " %2, %1, %0\n"
+
+#define	MOP(sum, tmp, addr)						\
+	"addc %2, 0, %0"						\
+	: "=r" (sum), "=&r" (tmp) : "0" (sum), "r" (addr) : "cc"
+
+u_short
+in_cksum_skip(struct mbuf *m, int len, int skip)
+{
+	u_short *w;
+	unsigned long tmp, sum = 0;
+	int mlen = 0;
+	int byte_swapped = 0;
+	u_short	su = 0;
+
+	len -= skip;
+	for (; skip > 0 && m != NULL; m = m->m_next) {
+		if (m->m_len > skip) {
+			mlen = m->m_len - skip;
+			w = (u_short *)(mtod(m, u_char *) + skip);
+			goto skip_start;
+		} else
+			skip -= m->m_len;
+	}
+
+	for (; m != NULL && len > 0; m = m->m_next) {
+		if (m->m_len == 0)
+			continue;
+		w = mtod(m, u_short *);
+		if (mlen == -1) {
+			/*
+			 * The first byte of this mbuf is the continuation
+			 * of a word spanning between this mbuf and the
+			 * last mbuf.
+			 *
+			 * The high order byte of su is already saved when
+			 * scanning previous mbuf.  sum was REDUCEd when we
+			 * found mlen == -1
+			 */
+			sum += su | *(u_char *)w;
+			w = (u_short *)((u_char *)w + 1);
+			mlen = m->m_len - 1;
+			len--;
+		} else
+			mlen = m->m_len;
+skip_start:
+		if (len < mlen)
+			mlen = len;
+		len -= mlen;
+		/*
+		 * Force to a 8-byte boundary first so that we can use
+		 * LD64_ADD32.
+		 */
+		if (((u_long)w & 7) != 0) {
+			REDUCE(sum, tmp);
+			if (((u_long)w & 1) != 0 && mlen >= 1) {
+				sum <<= 8;
+				su = *(u_char *)w << 8;
+				w = (u_short *)((u_char *)w + 1);
+				mlen--;
+				byte_swapped = 1;
+			}
+			if (((u_long)w & 2) != 0 && mlen >= 2) {
+				sum += *w++;
+				mlen -= 2;
+			}
+			if (((u_long)w & 4) != 0 && mlen >= 4) {
+				__asm(
+				    LD32_ADD32(0, cc)
+				    MOP(sum, tmp, w)
+				);
+				w += 2;
+				mlen -= 4;
+			}
+		}
+		/*
+		 * Do as much of the checksum as possible 64 bits at at time.
+		 * In fact, this loop is unrolled to make overhead from
+		 * branches &c small.
+		 */
+		for (; mlen >= 64; mlen -= 64) {
+			__asm(
+			    LD64_ADD32(0, cc)
+			    LD64_ADD32(8, ccc)
+			    LD64_ADD32(16, ccc)
+			    LD64_ADD32(24, ccc)
+			    LD64_ADD32(32, ccc)
+			    LD64_ADD32(40, ccc)
+			    LD64_ADD32(48, ccc)
+			    LD64_ADD32(56, ccc)
+			    MOP(sum, tmp, w)
+			);
+			w += 32;
+		}
+		if (mlen >= 32) {
+			__asm(
+			    LD64_ADD32(0, cc)
+			    LD64_ADD32(8, ccc)
+			    LD64_ADD32(16, ccc)
+			    LD64_ADD32(24, ccc)
+			    MOP(sum, tmp, w)
+			);
+			w += 16;
+			mlen -= 32;
+		}
+		if (mlen >= 16) {
+			__asm(
+			    LD64_ADD32(0, cc)
+			    LD64_ADD32(8, ccc)
+			    MOP(sum, tmp, w)
+			);
+			w += 8;
+			mlen -= 16;
+		}
+		if (mlen >= 8) {
+			__asm(
+			    LD64_ADD32(0, cc)
+			    MOP(sum, tmp, w)
+			);
+			w += 4;
+			mlen -= 8;
+		}
+		REDUCE(sum, tmp);
+		while ((mlen -= 2) >= 0)
+			sum += *w++;
+		if (byte_swapped) {
+			sum <<= 8;
+			byte_swapped = 0;
+			if (mlen == -1) {
+				su |= *(u_char *)w;
+				sum += su;
+				mlen = 0;
+			} else
+				mlen = -1;
+		} else if (mlen == -1) {
+			/*
+			 * This mbuf has odd number of bytes.
+			 * There could be a word split between
+			 * this mbuf and the next mbuf.
+			 * Save the last byte (to prepend to next mbuf).
+			 */
+			su = *(u_char *)w << 8;
+		}
+	}
+
+	if (len)
+		printf("%s: out of data by %d\n", __func__, len);
+	if (mlen == -1) {
+		/*
+		 * The last mbuf has odd # of bytes.  Follow the
+		 * standard (the odd byte is shifted left by 8 bits).
+		 */
+		sum += su & 0xff00;
+	}
+	REDUCE(sum, tmp);
+	return (~sum & 0xffff);
+}


Property changes on: trunk/sys/sparc64/sparc64/in_cksum.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/interrupt.S
===================================================================
--- trunk/sys/sparc64/sparc64/interrupt.S	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/interrupt.S	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,232 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 Jake Burkholder.
+ * 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.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/interrupt.S 245017 2013-01-03 23:12:08Z marius $");
+
+#include <machine/asi.h>
+#include <machine/asmacros.h>
+#include <machine/intr_machdep.h>
+#include <machine/pstate.h>
+#include <machine/ver.h>
+
+#include "assym.s"
+
+/*
+ * Handle a vectored interrupt.
+ *
+ * This is either a data bearing mondo vector interrupt, or a cross trap
+ * request from another cpu.  In either case the hardware supplies an
+ * interrupt packet, in the form of 3 data words which are read from internal
+ * registers.  A data bearing mondo vector packet consists of an interrupt
+ * number in the first data word, and zero in 2nd and 3rd.  We use the
+ * interrupt number to find the function, argument and priority from the
+ * intr_vector table, allocate and fill in an intr_request from the per-cpu
+ * free list, link it onto the per-cpu active list and finally post a softint
+ * at the desired priority.  Cross trap requests come in 2 forms, direct
+ * and queued.  Direct requests are distinguished by the first data word
+ * being zero.  The 2nd data word carries a function to call and the 3rd
+ * an argument to pass.  The function is jumped to directly.  It executes
+ * in nucleus context on interrupt globals and with all interrupts disabled,
+ * therefore it must be fast, and the things that it can do are limited.
+ * Queued cross trap requests are handled much like mondo vectors, except
+ * that the function, argument and priority are contained in the interrupt
+ * packet itself.  They are distinguished by the upper 4 bits of the data
+ * word being non-zero, which specifies the priority of the softint to
+ * deliver.
+ *
+ * Register usage:
+ *	%g1 - pointer to intr_request
+ *	%g2 - pointer to intr_vector, temp once required data is loaded
+ *	%g3 - interrupt number for mondo vectors, unused otherwise
+ *	%g4 - function, from the interrupt packet for cross traps, or
+ *	      loaded from the interrupt registers for mondo vecors
+ *	%g5 - argument, as above for %g4
+ *	%g6 - softint priority
+ */
+ENTRY(intr_vector)
+	/*
+	 * Load the interrupt packet from the hardware.
+	 */
+	wr	%g0, ASI_SDB_INTR_R, %asi
+	ldxa	[%g0 + AA_SDB_INTR_D0] %asi, %g3
+	ldxa	[%g0 + AA_SDB_INTR_D1] %asi, %g4
+	ldxa	[%g0 + AA_SDB_INTR_D2] %asi, %g5
+	stxa	%g0, [%g0] ASI_INTR_RECEIVE
+	membar	#Sync
+
+	/*
+	 * If the first data word is zero this is a direct cross trap request.
+	 * The 2nd word points to code to execute and the 3rd is an argument
+	 * to pass.  Jump to it.
+	 */
+	brnz,pt %g3, 1f
+	/*
+	 * NB: Zeus CPUs set some undocumented bits in the first data word.
+	 */
+	 and	%g3, IV_MAX - 1, %g3
+	jmpl	%g4, %g0
+	 nop
+	/* NOTREACHED */
+
+	/*
+	 * If the high 4 bits of the 1st data word are non-zero, this is a
+	 * queued cross trap request to be delivered as a softint.  The high
+	 * 4 bits of the 1st data word specify a priority, and the 2nd and
+	 * 3rd a function and argument.
+	 */
+1:	srlx	%g3, 60, %g6
+	brnz,a,pn %g6, 2f
+	 clr	%g3
+
+	/*
+	 * Find the function, argument and desired priority from the
+	 * intr_vector table.
+	 */
+	SET(intr_vectors, %g4, %g2)
+	sllx	%g3, IV_SHIFT, %g4
+	add	%g2, %g4, %g2
+
+	ldx	[%g2 + IV_FUNC], %g4
+	ldx	[%g2 + IV_ARG], %g5
+	lduw	[%g2 + IV_PRI], %g6
+
+	/*
+	 * Get an intr_request from the free list.  There should always be one
+	 * unless we are getting an interrupt storm from stray interrupts, in
+	 * which case the we will deference a NULL pointer and panic.
+	 */
+2:	ldx	[PCPU(IRFREE)], %g1
+	ldx	[%g1 + IR_NEXT], %g2
+	stx	%g2, [PCPU(IRFREE)]
+
+	/*
+	 * Store the vector number, function, argument and priority.
+	 */
+	stw	%g3, [%g1 + IR_VEC]
+	stx	%g4, [%g1 + IR_FUNC]
+	stx	%g5, [%g1 + IR_ARG]
+	stw	%g6, [%g1 + IR_PRI]
+
+	/*
+	 * Link it onto the end of the active list.
+	 */
+	stx	%g0, [%g1 + IR_NEXT]
+	ldx	[PCPU(IRTAIL)], %g4
+	stx	%g1, [%g4]
+	add	%g1, IR_NEXT, %g1
+	stx	%g1, [PCPU(IRTAIL)]
+
+	/*
+	 * Trigger a softint at the level indicated by the priority.
+	 */
+	mov	1, %g1
+	sllx	%g1, %g6, %g1
+	wr	%g1, 0, %set_softint
+
+	/*
+	 * Done, retry the instruction.
+	 */
+	retry
+END(intr_vector)
+
+ENTRY(intr_vector_stray)
+	/*
+	 * SPARC64-VI trigger stray vector interrupts in order to indicate
+	 * uncorrectable errors in interrupt packets, which still need to be
+	 * acknowledged though.
+	 * US-IV occasionally trigger stray vector interrupts for reasons
+	 * unknown accompanied by a state in which they even fault on locked
+	 * TLB entries so we can't even log these here.  Just retrying the
+	 * instruction in that case gets the CPU back on track.
+	 */
+	rdpr	%ver, %g1
+	srlx	%g1, VER_IMPL_SHIFT, %g1
+	sll	%g1, VER_IMPL_SIZE, %g1
+	srl	%g1, VER_IMPL_SIZE, %g1
+	cmp	%g1, CPU_IMPL_SPARC64VI
+	bne,a,pn %icc, 1f
+	 nop
+	stxa	%g0, [%g0] ASI_INTR_RECEIVE
+	membar	#Sync
+
+1:	retry
+END(intr_vector_stray)
+
+ENTRY(intr_fast)
+	save	%sp, -CCFSZ, %sp
+
+	/*
+	 * Disable interrupts while we fiddle with the interrupt request lists
+	 * as interrupts at levels higher than what got us here aren't blocked.
+	 */
+1:	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	ldx	[PCPU(IRHEAD)], %l0
+	brnz,a,pt %l0, 2f
+	 nop
+
+	wrpr	%g0, PSTATE_KERNEL, %pstate
+
+	ret
+	 restore
+
+2:	ldx	[%l0 + IR_NEXT], %l1
+	brnz,pt	%l1, 3f
+	 stx	%l1, [PCPU(IRHEAD)]
+	PCPU_ADDR(IRHEAD, %l1)
+	stx	%l1, [PCPU(IRTAIL)]
+
+3:	ldx	[%l0 + IR_FUNC], %o0
+	ldx	[%l0 + IR_ARG], %o1
+	lduw	[%l0 + IR_VEC], %l2
+
+	ldx	[PCPU(IRFREE)], %l1
+	stx	%l1, [%l0 + IR_NEXT]
+	stx	%l0, [PCPU(IRFREE)]
+
+	wrpr	%g0, PSTATE_KERNEL, %pstate
+
+	KASSERT(%o0, "intr_fast: ir_func null")
+	call	%o0
+	 mov	%o1, %o0
+
+	/* intrcnt[intr_countp[%l2]]++ */
+	SET(intrcnt, %l7, %l3)		/* %l3 = intrcnt */
+	prefetcha [%l3] ASI_N, 1
+	SET(intr_countp, %l7, %l4)	/* %l4 = intr_countp */
+	sllx	%l2, 1, %l2		/* %l2 = vec << 1 */
+	lduh	[%l4 + %l2], %l4	/* %l4 = intr_countp[%l2] */
+	sllx	%l4, 3, %l4		/* %l4 = intr_countp[%l2] << 3 */
+	add	%l4, %l3, %l4		/* %l4 = intrcnt[intr_countp[%l2]] */
+	ldx	[%l4], %l2
+	inc	%l2
+	stx	%l2, [%l4]
+
+	ba,a	%xcc, 1b
+	 nop
+END(intr_fast)


Property changes on: trunk/sys/sparc64/sparc64/interrupt.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/intr_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/intr_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/intr_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,558 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1991 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.
+ * 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.
+ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ *	from: @(#)isa.c	7.2 (Berkeley) 5/13/91
+ *	form: src/sys/i386/isa/intr_machdep.c,v 1.57 2001/07/20
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/intr_machdep.c 241780 2012-10-20 12:07:48Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/errno.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/smp.h>
+#include <sys/sx.h>
+
+#include <machine/frame.h>
+#include <machine/intr_machdep.h>
+
+#define	MAX_STRAY_LOG	5
+
+CTASSERT((1 << IV_SHIFT) == sizeof(struct intr_vector));
+
+ih_func_t *intr_handlers[PIL_MAX];
+uint16_t pil_countp[PIL_MAX];
+static uint16_t pil_stray_count[PIL_MAX];
+
+struct intr_vector intr_vectors[IV_MAX];
+uint16_t intr_countp[IV_MAX];
+static uint16_t intr_stray_count[IV_MAX];
+
+static const char *const pil_names[] = {
+	"stray",
+	"low",		/* PIL_LOW */
+	"preempt",	/* PIL_PREEMPT */
+	"ithrd",	/* PIL_ITHREAD */
+	"rndzvs",	/* PIL_RENDEZVOUS */
+	"ast",		/* PIL_AST */
+	"hardclock",	/* PIL_HARDCLOCK */
+	"stray", "stray", "stray", "stray",
+	"filter",	/* PIL_FILTER */
+	"bridge",	/* PIL_BRIDGE */
+	"stop",		/* PIL_STOP */
+	"tick",		/* PIL_TICK */
+};
+
+/* protect the intr_vectors table */
+static struct sx intr_table_lock;
+/* protect intrcnt_index */
+static struct mtx intrcnt_lock;
+
+#ifdef SMP
+static int assign_cpu;
+
+static void intr_assign_next_cpu(struct intr_vector *iv);
+static void intr_shuffle_irqs(void *arg __unused);
+#endif
+
+static int intr_assign_cpu(void *arg, u_char cpu);
+static void intr_execute_handlers(void *);
+static void intr_stray_level(struct trapframe *);
+static void intr_stray_vector(void *);
+static int intrcnt_setname(const char *, int);
+static void intrcnt_updatename(int, const char *, int);
+
+static void
+intrcnt_updatename(int vec, const char *name, int ispil)
+{
+	static int intrcnt_index, stray_pil_index, stray_vec_index;
+	int name_index;
+
+	mtx_lock_spin(&intrcnt_lock);
+	if (intrnames[0] == '\0') {
+		/* for bitbucket */
+		if (bootverbose)
+			printf("initalizing intr_countp\n");
+		intrcnt_setname("???", intrcnt_index++);
+
+		stray_vec_index = intrcnt_index++;
+		intrcnt_setname("stray", stray_vec_index);
+		for (name_index = 0; name_index < IV_MAX; name_index++)
+			intr_countp[name_index] = stray_vec_index;
+
+		stray_pil_index = intrcnt_index++;
+		intrcnt_setname("pil", stray_pil_index);
+		for (name_index = 0; name_index < PIL_MAX; name_index++)
+			pil_countp[name_index] = stray_pil_index;
+	}
+
+	if (name == NULL)
+		name = "???";
+
+	if (!ispil && intr_countp[vec] != stray_vec_index)
+		name_index = intr_countp[vec];
+	else if (ispil && pil_countp[vec] != stray_pil_index)
+		name_index = pil_countp[vec];
+	else
+		name_index = intrcnt_index++;
+
+	if (intrcnt_setname(name, name_index))
+		name_index = 0;
+
+	if (!ispil)
+		intr_countp[vec] = name_index;
+	else
+		pil_countp[vec] = name_index;
+	mtx_unlock_spin(&intrcnt_lock);
+}
+
+static int
+intrcnt_setname(const char *name, int index)
+{
+
+	if ((MAXCOMLEN + 1) * index >= sintrnames)
+		return (E2BIG);
+	snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s",
+	    MAXCOMLEN, name);
+	return (0);
+}
+
+void
+intr_setup(int pri, ih_func_t *ihf, int vec, iv_func_t *ivf, void *iva)
+{
+	char pilname[MAXCOMLEN + 1];
+	register_t s;
+
+	s = intr_disable();
+	if (vec != -1) {
+		intr_vectors[vec].iv_func = ivf;
+		intr_vectors[vec].iv_arg = iva;
+		intr_vectors[vec].iv_pri = pri;
+		intr_vectors[vec].iv_vec = vec;
+	}
+	intr_handlers[pri] = ihf;
+	intr_restore(s);
+	snprintf(pilname, MAXCOMLEN + 1, "pil%d: %s", pri, pil_names[pri]);
+	intrcnt_updatename(pri, pilname, 1);
+}
+
+static void
+intr_stray_level(struct trapframe *tf)
+{
+	uint64_t level;
+
+	level = tf->tf_level;
+	if (pil_stray_count[level] < MAX_STRAY_LOG) {
+		printf("stray level interrupt %ld\n", level);
+		pil_stray_count[level]++;
+		if (pil_stray_count[level] >= MAX_STRAY_LOG)
+			printf("got %d stray level interrupt %ld's: not "
+			    "logging anymore\n", MAX_STRAY_LOG, level);
+	}
+}
+
+static void
+intr_stray_vector(void *cookie)
+{
+	struct intr_vector *iv;
+	u_int vec;
+
+	iv = cookie;
+	vec = iv->iv_vec;
+	if (intr_stray_count[vec] < MAX_STRAY_LOG) {
+		printf("stray vector interrupt %d\n", vec);
+		intr_stray_count[vec]++;
+		if (intr_stray_count[vec] >= MAX_STRAY_LOG)
+			printf("got %d stray vector interrupt %d's: not "
+			    "logging anymore\n", MAX_STRAY_LOG, vec);
+	}
+}
+
+void
+intr_init1()
+{
+	int i;
+
+	/* Mark all interrupts as being stray. */
+	for (i = 0; i < PIL_MAX; i++)
+		intr_handlers[i] = intr_stray_level;
+	for (i = 0; i < IV_MAX; i++) {
+		intr_vectors[i].iv_func = intr_stray_vector;
+		intr_vectors[i].iv_arg = &intr_vectors[i];
+		intr_vectors[i].iv_pri = PIL_LOW;
+		intr_vectors[i].iv_vec = i;
+		intr_vectors[i].iv_refcnt = 0;
+	}
+	intr_handlers[PIL_LOW] = intr_fast;
+}
+
+void
+intr_init2()
+{
+
+	sx_init(&intr_table_lock, "intr sources");
+	mtx_init(&intrcnt_lock, "intrcnt", NULL, MTX_SPIN);
+}
+
+static int
+intr_assign_cpu(void *arg, u_char cpu)
+{
+#ifdef SMP
+	struct pcpu *pc;
+	struct intr_vector *iv;
+
+	/*
+	 * Don't do anything during early boot.  We will pick up the
+	 * assignment once the APs are started.
+	 */
+	if (assign_cpu && cpu != NOCPU) {
+		pc = pcpu_find(cpu);
+		if (pc == NULL)
+			return (EINVAL);
+		iv = arg;
+		sx_xlock(&intr_table_lock);
+		iv->iv_mid = pc->pc_mid;
+		iv->iv_ic->ic_assign(iv);
+		sx_xunlock(&intr_table_lock);
+	}
+	return (0);
+#else
+	return (EOPNOTSUPP);
+#endif
+}
+
+static void
+intr_execute_handlers(void *cookie)
+{
+	struct intr_vector *iv;
+
+	iv = cookie;
+	if (__predict_false(intr_event_handle(iv->iv_event, NULL) != 0))
+		intr_stray_vector(iv);
+}
+
+int
+intr_controller_register(int vec, const struct intr_controller *ic,
+    void *icarg)
+{
+	struct intr_event *ie;
+	struct intr_vector *iv;
+	int error;
+
+	if (vec < 0 || vec >= IV_MAX)
+		return (EINVAL);
+	sx_xlock(&intr_table_lock);
+	iv = &intr_vectors[vec];
+	ie = iv->iv_event;
+	sx_xunlock(&intr_table_lock);
+	if (ie != NULL)
+		return (EEXIST);
+	error = intr_event_create(&ie, iv, 0, vec, NULL, ic->ic_clear,
+	    ic->ic_clear, intr_assign_cpu, "vec%d:", vec);
+	if (error != 0)
+		return (error);
+	sx_xlock(&intr_table_lock);
+	if (iv->iv_event != NULL) {
+		sx_xunlock(&intr_table_lock);
+		intr_event_destroy(ie);
+		return (EEXIST);
+	}
+	iv->iv_ic = ic;
+	iv->iv_icarg = icarg;
+	iv->iv_event = ie;
+	iv->iv_mid = PCPU_GET(mid);
+	sx_xunlock(&intr_table_lock);
+	return (0);
+}
+
+int
+inthand_add(const char *name, int vec, driver_filter_t *filt,
+    driver_intr_t *handler, void *arg, int flags, void **cookiep)
+{
+	const struct intr_controller *ic;
+	struct intr_event *ie;
+	struct intr_handler *ih;
+	struct intr_vector *iv;
+	int error, filter;
+
+	if (vec < 0 || vec >= IV_MAX)
+		return (EINVAL);
+	/*
+	 * INTR_BRIDGE filters/handlers are special purpose only, allowing
+	 * them to be shared just would complicate things unnecessarily.
+	 */
+	if ((flags & INTR_BRIDGE) != 0 && (flags & INTR_EXCL) == 0)
+		return (EINVAL);
+	sx_xlock(&intr_table_lock);
+	iv = &intr_vectors[vec];
+	ic = iv->iv_ic;
+	ie = iv->iv_event;
+	sx_xunlock(&intr_table_lock);
+	if (ic == NULL || ie == NULL)
+		return (EINVAL);
+	error = intr_event_add_handler(ie, name, filt, handler, arg,
+	    intr_priority(flags), flags, cookiep);
+	if (error != 0)
+		return (error);
+	sx_xlock(&intr_table_lock);
+	/* Disable the interrupt while we fiddle with it. */
+	ic->ic_disable(iv);
+	iv->iv_refcnt++;
+	if (iv->iv_refcnt == 1)
+		intr_setup((flags & INTR_BRIDGE) != 0 ? PIL_BRIDGE :
+		    filt != NULL ? PIL_FILTER : PIL_ITHREAD, intr_fast,
+		    vec, intr_execute_handlers, iv);
+	else if (filt != NULL) {
+		/*
+		 * Check if we need to upgrade from PIL_ITHREAD to PIL_FILTER.
+		 * Given that apart from the on-board SCCs and UARTs shared
+		 * interrupts are rather uncommon on sparc64 this sould be
+		 * pretty rare in practice.
+		 */
+		filter = 0;
+		TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
+			if (ih->ih_filter != NULL && ih->ih_filter != filt) {
+				filter = 1;
+				break;
+			}
+		}
+		if (filter == 0)
+			intr_setup(PIL_FILTER, intr_fast, vec,
+			    intr_execute_handlers, iv);
+	}
+	intr_stray_count[vec] = 0;
+	intrcnt_updatename(vec, ie->ie_fullname, 0);
+#ifdef SMP
+	if (assign_cpu)
+		intr_assign_next_cpu(iv);
+#endif
+	ic->ic_enable(iv);
+	/* Ensure the interrupt is cleared, it might have triggered before. */
+	if (ic->ic_clear != NULL)
+		ic->ic_clear(iv);
+	sx_xunlock(&intr_table_lock);
+	return (0);
+}
+
+int
+inthand_remove(int vec, void *cookie)
+{
+	struct intr_vector *iv;
+	int error;
+
+	if (vec < 0 || vec >= IV_MAX)
+		return (EINVAL);
+	error = intr_event_remove_handler(cookie);
+	if (error == 0) {
+		/*
+		 * XXX: maybe this should be done regardless of whether
+		 * intr_event_remove_handler() succeeded?
+		 */
+		sx_xlock(&intr_table_lock);
+		iv = &intr_vectors[vec];
+		iv->iv_refcnt--;
+		if (iv->iv_refcnt == 0) {
+			/*
+			 * Don't disable the interrupt for now, so that
+			 * stray interrupts get detected...
+			 */
+			intr_setup(PIL_LOW, intr_fast, vec,
+			    intr_stray_vector, iv);
+		}
+		sx_xunlock(&intr_table_lock);
+	}
+	return (error);
+}
+
+/* Add a description to an active interrupt handler. */
+int
+intr_describe(int vec, void *ih, const char *descr)
+{
+	struct intr_vector *iv;
+	int error;
+
+	if (vec < 0 || vec >= IV_MAX)
+		return (EINVAL);
+	sx_xlock(&intr_table_lock);
+	iv = &intr_vectors[vec];
+	if (iv == NULL) {
+		sx_xunlock(&intr_table_lock);
+		return (EINVAL);
+	}
+	error = intr_event_describe_handler(iv->iv_event, ih, descr);
+	if (error) {
+		sx_xunlock(&intr_table_lock);
+		return (error);
+	}
+	intrcnt_updatename(vec, iv->iv_event->ie_fullname, 0);
+	sx_xunlock(&intr_table_lock);
+	return (error);
+}
+
+#ifdef SMP
+/*
+ * Support for balancing interrupt sources across CPUs.  For now we just
+ * allocate CPUs round-robin.
+ */
+
+static cpuset_t intr_cpus = CPUSET_T_INITIALIZER(0x1);
+static int current_cpu;
+
+static void
+intr_assign_next_cpu(struct intr_vector *iv)
+{
+	struct pcpu *pc;
+
+	sx_assert(&intr_table_lock, SA_XLOCKED);
+
+	/*
+	 * Assign this source to a CPU in a round-robin fashion.
+	 */
+	pc = pcpu_find(current_cpu);
+	if (pc == NULL)
+		return;
+	iv->iv_mid = pc->pc_mid;
+	iv->iv_ic->ic_assign(iv);
+	do {
+		current_cpu++;
+		if (current_cpu > mp_maxid)
+			current_cpu = 0;
+	} while (!CPU_ISSET(current_cpu, &intr_cpus));
+}
+
+/* Attempt to bind the specified IRQ to the specified CPU. */
+int
+intr_bind(int vec, u_char cpu)
+{
+	struct intr_vector *iv;
+	int error;
+
+	if (vec < 0 || vec >= IV_MAX)
+		return (EINVAL);
+	sx_xlock(&intr_table_lock);
+	iv = &intr_vectors[vec];
+	if (iv == NULL) {
+		sx_xunlock(&intr_table_lock);
+		return (EINVAL);
+	}
+	error = intr_event_bind(iv->iv_event, cpu);
+	sx_xunlock(&intr_table_lock);
+	return (error);
+}
+
+/*
+ * Add a CPU to our mask of valid CPUs that can be destinations of
+ * interrupts.
+ */
+void
+intr_add_cpu(u_int cpu)
+{
+
+	if (cpu >= MAXCPU)
+		panic("%s: Invalid CPU ID", __func__);
+	if (bootverbose)
+		printf("INTR: Adding CPU %d as a target\n", cpu);
+
+	CPU_SET(cpu, &intr_cpus);
+}
+
+/*
+ * Distribute all the interrupt sources among the available CPUs once the
+ * APs have been launched.
+ */
+static void
+intr_shuffle_irqs(void *arg __unused)
+{
+	struct pcpu *pc;
+	struct intr_vector *iv;
+	int i;
+
+	/* Don't bother on UP. */
+	if (mp_ncpus == 1)
+		return;
+
+	sx_xlock(&intr_table_lock);
+	assign_cpu = 1;
+	for (i = 0; i < IV_MAX; i++) {
+		iv = &intr_vectors[i];
+		if (iv != NULL && iv->iv_refcnt > 0) {
+			/*
+			 * If this event is already bound to a CPU,
+			 * then assign the source to that CPU instead
+			 * of picking one via round-robin.
+			 */
+			if (iv->iv_event->ie_cpu != NOCPU &&
+			    (pc = pcpu_find(iv->iv_event->ie_cpu)) != NULL) {
+				iv->iv_mid = pc->pc_mid;
+				iv->iv_ic->ic_assign(iv);
+			} else
+				intr_assign_next_cpu(iv);
+		}
+	}
+	sx_xunlock(&intr_table_lock);
+}
+SYSINIT(intr_shuffle_irqs, SI_SUB_SMP, SI_ORDER_SECOND, intr_shuffle_irqs,
+    NULL);
+#endif


Property changes on: trunk/sys/sparc64/sparc64/intr_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/iommu.c
===================================================================
--- trunk/sys/sparc64/sparc64/iommu.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/iommu.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,1216 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * 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 ``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.
+ *
+ *	from: NetBSD: iommu.c,v 1.82 2008/05/30 02:29:37 mrg Exp
+ */
+/*-
+ * Copyright (c) 1999-2002 Eduardo Horvath
+ * Copyright (c) 2001-2003 Thomas Moestl
+ * Copyright (c) 2007, 2009 Marius Strobl <marius at 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, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: sbus.c,v 1.50 2002/06/20 18:26:24 eeh Exp
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/iommu.c 246713 2013-02-12 16:57:20Z kib $");
+
+/*
+ * UltraSPARC IOMMU support; used by both the PCI and SBus code.
+ *
+ * TODO:
+ * - Support sub-page boundaries.
+ * - Fix alignment handling for small allocations (the possible page offset
+ *   of malloc()ed memory is not handled at all).  Revise interaction of
+ *   alignment with the load_mbuf and load_uio functions.
+ * - Handle lowaddr and highaddr in some way, and try to work out a way
+ *   for filter callbacks to work.  Currently, only lowaddr is honored
+ *   in that no addresses above it are considered at all.
+ * - Implement BUS_DMA_ALLOCNOW in bus_dma_tag_create as far as possible.
+ * - Check the possible return values and callback error arguments;
+ *   the callback currently gets called in error conditions where it should
+ *   not be.
+ * - When running out of DVMA space, return EINPROGRESS in the non-
+ *   BUS_DMA_NOWAIT case and delay the callback until sufficient space
+ *   becomes available.
+ */
+
+#include "opt_iommu.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+
+#include <machine/asi.h>
+#include <machine/bus.h>
+#include <machine/bus_private.h>
+#include <machine/iommureg.h>
+#include <machine/pmap.h>
+#include <machine/resource.h>
+#include <machine/ver.h>
+
+#include <sys/rman.h>
+
+#include <machine/iommuvar.h>
+
+/*
+ * Tuning constants
+ */
+#define	IOMMU_MAX_PRE		(32 * 1024)
+#define	IOMMU_MAX_PRE_SEG	3
+
+/* Threshold for using the streaming buffer */
+#define	IOMMU_STREAM_THRESH	128
+
+static MALLOC_DEFINE(M_IOMMU, "dvmamem", "IOMMU DVMA Buffers");
+
+static	int iommu_strbuf_flush_sync(struct iommu_state *);
+#ifdef IOMMU_DIAG
+static	void iommu_diag(struct iommu_state *, vm_offset_t va);
+#endif
+
+/*
+ * Helpers
+ */
+#define	IOMMU_READ8(is, reg, off)					\
+	bus_space_read_8((is)->is_bustag, (is)->is_bushandle,		\
+	    (is)->reg + (off))
+#define	IOMMU_WRITE8(is, reg, off, v)					\
+	bus_space_write_8((is)->is_bustag, (is)->is_bushandle,		\
+	    (is)->reg + (off), (v))
+
+#define	IOMMU_HAS_SB(is)						\
+	((is)->is_sb[0] != 0 || (is)->is_sb[1] != 0)
+
+/*
+ * Always overallocate one page; this is needed to handle alignment of the
+ * buffer, so it makes sense using a lazy allocation scheme.
+ */
+#define	IOMMU_SIZE_ROUNDUP(sz)						\
+	(round_io_page(sz) + IO_PAGE_SIZE)
+
+#define	IOMMU_SET_TTE(is, va, tte)					\
+	((is)->is_tsb[IOTSBSLOT(va)] = (tte))
+#define	IOMMU_GET_TTE(is, va)						\
+	(is)->is_tsb[IOTSBSLOT(va)]
+
+/* Resource helpers */
+#define	IOMMU_RES_START(res)						\
+	((bus_addr_t)rman_get_start(res) << IO_PAGE_SHIFT)
+#define	IOMMU_RES_END(res)						\
+	((bus_addr_t)(rman_get_end(res) + 1) << IO_PAGE_SHIFT)
+#define	IOMMU_RES_SIZE(res)						\
+	((bus_size_t)rman_get_size(res) << IO_PAGE_SHIFT)
+
+/* Helpers for struct bus_dmamap_res */
+#define	BDR_START(r)	IOMMU_RES_START((r)->dr_res)
+#define	BDR_END(r)	IOMMU_RES_END((r)->dr_res)
+#define	BDR_SIZE(r)	IOMMU_RES_SIZE((r)->dr_res)
+
+/* Locking macros */
+#define	IS_LOCK(is)	mtx_lock(&is->is_mtx)
+#define	IS_LOCK_ASSERT(is)	mtx_assert(&is->is_mtx, MA_OWNED)
+#define	IS_UNLOCK(is)	mtx_unlock(&is->is_mtx)
+
+/* Flush a page from the TLB.  No locking required, since this is atomic. */
+static __inline void
+iommu_tlb_flush(struct iommu_state *is, bus_addr_t va)
+{
+
+	if ((is->is_flags & IOMMU_FIRE) != 0)
+		/*
+		 * Direct page flushing is not supported and also not
+		 * necessary due to cache snooping.
+		 */
+		return;
+	IOMMU_WRITE8(is, is_iommu, IMR_FLUSH, va);
+}
+
+/*
+ * Flush a page from the streaming buffer.  No locking required, since this
+ * is atomic.
+ */
+static __inline void
+iommu_strbuf_flushpg(struct iommu_state *is, bus_addr_t va)
+{
+	int i;
+
+	for (i = 0; i < 2; i++)
+		if (is->is_sb[i] != 0)
+			IOMMU_WRITE8(is, is_sb[i], ISR_PGFLUSH, va);
+}
+
+/*
+ * Flush an address from the streaming buffer(s); this is an asynchronous
+ * operation.  To make sure that it has completed, iommu_strbuf_sync() needs
+ * to be called.  No locking required.
+ */
+static __inline void
+iommu_strbuf_flush(struct iommu_state *is, bus_addr_t va)
+{
+
+	iommu_strbuf_flushpg(is, va);
+}
+
+/* Synchronize all outstanding flush operations. */
+static __inline void
+iommu_strbuf_sync(struct iommu_state *is)
+{
+
+	IS_LOCK_ASSERT(is);
+	iommu_strbuf_flush_sync(is);
+}
+
+/* LRU queue handling for lazy resource allocation. */
+static __inline void
+iommu_map_insq(struct iommu_state *is, bus_dmamap_t map)
+{
+
+	IS_LOCK_ASSERT(is);
+	if (!SLIST_EMPTY(&map->dm_reslist)) {
+		if (map->dm_onq)
+			TAILQ_REMOVE(&is->is_maplruq, map, dm_maplruq);
+		TAILQ_INSERT_TAIL(&is->is_maplruq, map, dm_maplruq);
+		map->dm_onq = 1;
+	}
+}
+
+static __inline void
+iommu_map_remq(struct iommu_state *is, bus_dmamap_t map)
+{
+
+	IS_LOCK_ASSERT(is);
+	if (map->dm_onq)
+		TAILQ_REMOVE(&is->is_maplruq, map, dm_maplruq);
+	map->dm_onq = 0;
+}
+
+/*
+ * initialise the UltraSPARC IOMMU (PCI or SBus):
+ *	- allocate and setup the iotsb.
+ *	- enable the IOMMU
+ *	- initialise the streaming buffers (if they exist)
+ *	- create a private DVMA map.
+ */
+void
+iommu_init(const char *name, struct iommu_state *is, u_int tsbsize,
+    uint32_t iovabase, u_int resvpg)
+{
+	vm_size_t size;
+	vm_offset_t offs;
+	uint64_t end, obpmap, obpptsb, tte;
+	u_int maxtsbsize, obptsbentries, obptsbsize, slot, tsbentries;
+	int i;
+
+	/*
+	 * Setup the IOMMU.
+	 *
+	 * The sun4u IOMMU is part of the PCI or SBus controller so we
+	 * will deal with it here..
+	 *
+	 * The IOMMU address space always ends at 0xffffe000, but the starting
+	 * address depends on the size of the map.  The map size is 1024 * 2 ^
+	 * is->is_tsbsize entries, where each entry is 8 bytes.  The start of
+	 * the map can be calculated by (0xffffe000 << (8 + is->is_tsbsize)).
+	 */
+	if ((is->is_flags & IOMMU_FIRE) != 0) {
+		maxtsbsize = IOMMU_TSB512K;
+		/*
+		 * We enable bypass in order to be able to use a physical
+		 * address for the event queue base.
+		 */
+		is->is_cr = IOMMUCR_SE | IOMMUCR_CM_C_TLB_TBW | IOMMUCR_BE;
+	} else {
+		maxtsbsize = IOMMU_TSB128K;
+		is->is_cr = (tsbsize << IOMMUCR_TSBSZ_SHIFT) | IOMMUCR_DE;
+	}
+	if (tsbsize > maxtsbsize)
+		panic("%s: unsupported TSB size	", __func__);
+	tsbentries = IOMMU_TSBENTRIES(tsbsize);
+	is->is_cr |= IOMMUCR_EN;
+	is->is_tsbsize = tsbsize;
+	is->is_dvmabase = iovabase;
+	if (iovabase == -1)
+		is->is_dvmabase = IOTSB_VSTART(is->is_tsbsize);
+
+	size = IOTSB_BASESZ << is->is_tsbsize;
+	printf("%s: DVMA map: %#lx to %#lx %d entries%s\n", name,
+	    is->is_dvmabase, is->is_dvmabase +
+	    (size << (IO_PAGE_SHIFT - IOTTE_SHIFT)) - 1, tsbentries,
+	    IOMMU_HAS_SB(is) ? ", streaming buffer" : "");
+
+	/*
+	 * Set up resource mamangement.
+	 */
+	mtx_init(&is->is_mtx, "iommu", NULL, MTX_DEF);
+	end = is->is_dvmabase + (size << (IO_PAGE_SHIFT - IOTTE_SHIFT));
+	is->is_dvma_rman.rm_type = RMAN_ARRAY;
+	is->is_dvma_rman.rm_descr = "DVMA Memory";
+	if (rman_init(&is->is_dvma_rman) != 0 ||
+	    rman_manage_region(&is->is_dvma_rman,
+	    (is->is_dvmabase >> IO_PAGE_SHIFT) + resvpg,
+	    (end >> IO_PAGE_SHIFT) - 1) != 0)
+		panic("%s: could not initialize DVMA rman", __func__);
+	TAILQ_INIT(&is->is_maplruq);
+
+	/*
+	 * Allocate memory for I/O page tables.  They need to be
+	 * physically contiguous.
+	 */
+	is->is_tsb = contigmalloc(size, M_DEVBUF, M_NOWAIT, 0, ~0UL,
+	    PAGE_SIZE, 0);
+	if (is->is_tsb == NULL)
+		panic("%s: contigmalloc failed", __func__);
+	is->is_ptsb = pmap_kextract((vm_offset_t)is->is_tsb);
+	bzero(is->is_tsb, size);
+
+	/*
+	 * Add the PROM mappings to the kernel IOTSB if desired.
+	 * Note that the firmware of certain Darwin boards doesn't set
+	 * the TSB size correctly.
+	 */
+	if ((is->is_flags & IOMMU_FIRE) != 0)
+		obptsbsize = (IOMMU_READ8(is, is_iommu, IMR_TSB) &
+		    IOMMUTB_TSBSZ_MASK) >> IOMMUTB_TSBSZ_SHIFT;
+	else
+		obptsbsize = (IOMMU_READ8(is, is_iommu, IMR_CTL) &
+		    IOMMUCR_TSBSZ_MASK) >> IOMMUCR_TSBSZ_SHIFT;
+	obptsbentries = IOMMU_TSBENTRIES(obptsbsize);
+	if (bootverbose)
+		printf("%s: PROM IOTSB size: %d (%d entries)\n", name,
+		    obptsbsize, obptsbentries);
+	if ((is->is_flags & IOMMU_PRESERVE_PROM) != 0 &&
+	    !(PCPU_GET(impl) == CPU_IMPL_ULTRASPARCIIi && obptsbsize == 7)) {
+		if (obptsbentries > tsbentries)
+			panic("%s: PROM IOTSB entries exceed kernel",
+			    __func__);
+		obpptsb = IOMMU_READ8(is, is_iommu, IMR_TSB) &
+		    IOMMUTB_TB_MASK;
+		for (i = 0; i < obptsbentries; i++) {
+			tte = ldxa(obpptsb + i * 8, ASI_PHYS_USE_EC);
+			if ((tte & IOTTE_V) == 0)
+				continue;
+			slot = tsbentries - obptsbentries + i;
+			if (bootverbose)
+				printf("%s: adding PROM IOTSB slot %d "
+				    "(kernel slot %d) TTE: %#lx\n", name,
+				    i, slot, tte);
+			obpmap = (is->is_dvmabase + slot * IO_PAGE_SIZE) >>
+			    IO_PAGE_SHIFT;
+			if (rman_reserve_resource(&is->is_dvma_rman, obpmap,
+			    obpmap, IO_PAGE_SIZE >> IO_PAGE_SHIFT, RF_ACTIVE,
+			    NULL) == NULL)
+				panic("%s: could not reserve PROM IOTSB slot "
+				    "%d (kernel slot %d)", __func__, i, slot);
+			is->is_tsb[slot] = tte;
+		}
+	}
+
+	/*
+	 * Initialize streaming buffer, if it is there.
+	 */
+	if (IOMMU_HAS_SB(is)) {
+		/*
+		 * Find two 64-byte blocks in is_flush that are aligned on
+		 * a 64-byte boundary for flushing.
+		 */
+		offs = roundup2((vm_offset_t)is->is_flush,
+		    STRBUF_FLUSHSYNC_NBYTES);
+		for (i = 0; i < 2; i++, offs += STRBUF_FLUSHSYNC_NBYTES) {
+			is->is_flushva[i] = (uint64_t *)offs;
+			is->is_flushpa[i] = pmap_kextract(offs);
+		}
+	}
+
+	/*
+	 * Now actually start up the IOMMU.
+	 */
+	iommu_reset(is);
+}
+
+/*
+ * Streaming buffers don't exist on the UltraSPARC IIi; we should have
+ * detected that already and disabled them.  If not, we will notice that
+ * they aren't there when the STRBUF_EN bit does not remain.
+ */
+void
+iommu_reset(struct iommu_state *is)
+{
+	uint64_t tsb;
+	int i;
+
+	tsb = is->is_ptsb;
+	if ((is->is_flags & IOMMU_FIRE) != 0) {
+		tsb |= is->is_tsbsize;
+		IOMMU_WRITE8(is, is_iommu, IMR_CACHE_INVAL, ~0ULL);
+	}
+	IOMMU_WRITE8(is, is_iommu, IMR_TSB, tsb);
+	IOMMU_WRITE8(is, is_iommu, IMR_CTL, is->is_cr);
+
+	for (i = 0; i < 2; i++) {
+		if (is->is_sb[i] != 0) {
+			IOMMU_WRITE8(is, is_sb[i], ISR_CTL, STRBUF_EN |
+			    ((is->is_flags & IOMMU_RERUN_DISABLE) != 0 ?
+			    STRBUF_RR_DIS : 0));
+
+			/* No streaming buffers?  Disable them. */
+			if ((IOMMU_READ8(is, is_sb[i], ISR_CTL) &
+			    STRBUF_EN) == 0)
+				is->is_sb[i] = 0;
+		}
+	}
+
+	(void)IOMMU_READ8(is, is_iommu, IMR_CTL);
+}
+
+/*
+ * Enter a mapping into the TSB.  No locking required, since each TSB slot is
+ * uniquely assigned to a single map.
+ */
+static void
+iommu_enter(struct iommu_state *is, vm_offset_t va, vm_paddr_t pa,
+    int stream, int flags)
+{
+	uint64_t tte;
+
+	KASSERT(va >= is->is_dvmabase,
+	    ("%s: va %#lx not in DVMA space", __func__, va));
+	KASSERT(pa <= is->is_pmaxaddr,
+	    ("%s: XXX: physical address too large (%#lx)", __func__, pa));
+
+	tte = MAKEIOTTE(pa, !(flags & BUS_DMA_NOWRITE),
+	    !(flags & BUS_DMA_NOCACHE), stream);
+
+	IOMMU_SET_TTE(is, va, tte);
+	iommu_tlb_flush(is, va);
+#ifdef IOMMU_DIAG
+	IS_LOCK(is);
+	iommu_diag(is, va);
+	IS_UNLOCK(is);
+#endif
+}
+
+/*
+ * Remove mappings created by iommu_enter().  Flush the streaming buffer,
+ * but do not synchronize it.  Returns whether a streaming buffer flush
+ * was performed.
+ */
+static int
+iommu_remove(struct iommu_state *is, vm_offset_t va, vm_size_t len)
+{
+	int slot, streamed = 0;
+
+#ifdef IOMMU_DIAG
+	iommu_diag(is, va);
+#endif
+
+	KASSERT(va >= is->is_dvmabase,
+	    ("%s: va 0x%lx not in DVMA space", __func__, (u_long)va));
+	KASSERT(va + len >= va,
+	    ("%s: va 0x%lx + len 0x%lx wraps", __func__, (long)va, (long)len));
+
+	va = trunc_io_page(va);
+	while (len > 0) {
+		if ((IOMMU_GET_TTE(is, va) & IOTTE_STREAM) != 0) {
+			streamed = 1;
+			iommu_strbuf_flush(is, va);
+		}
+		len -= ulmin(len, IO_PAGE_SIZE);
+		IOMMU_SET_TTE(is, va, 0);
+		iommu_tlb_flush(is, va);
+		if ((is->is_flags & IOMMU_FLUSH_CACHE) != 0) {
+			slot = IOTSBSLOT(va);
+			if (len <= IO_PAGE_SIZE || slot % 8 == 7)
+				IOMMU_WRITE8(is, is_iommu, IMR_CACHE_FLUSH,
+				    is->is_ptsb + slot * 8);
+		}
+		va += IO_PAGE_SIZE;
+	}
+	return (streamed);
+}
+
+/* Decode an IOMMU fault for host bridge error handlers. */
+void
+iommu_decode_fault(struct iommu_state *is, vm_offset_t phys)
+{
+	bus_addr_t va;
+	long idx;
+
+	idx = phys - is->is_ptsb;
+	if (phys < is->is_ptsb ||
+	    idx > (PAGE_SIZE << is->is_tsbsize))
+		return;
+	va = is->is_dvmabase +
+	    (((bus_addr_t)idx >> IOTTE_SHIFT) << IO_PAGE_SHIFT);
+	printf("IOMMU fault virtual address %#lx\n", (u_long)va);
+}
+
+/*
+ * A barrier operation which makes sure that all previous streaming buffer
+ * flushes complete before it returns.
+ */
+static int
+iommu_strbuf_flush_sync(struct iommu_state *is)
+{
+	struct timeval cur, end;
+	int i;
+
+	IS_LOCK_ASSERT(is);
+	if (!IOMMU_HAS_SB(is))
+		return (0);
+
+	/*
+	 * Streaming buffer flushes:
+	 *
+	 *   1 Tell strbuf to flush by storing va to strbuf_pgflush.  If
+	 *     we're not on a cache line boundary (64-bits):
+	 *   2 Store 0 in flag
+	 *   3 Store pointer to flag in flushsync
+	 *   4 wait till flushsync becomes 0x1
+	 *
+	 * If it takes more than .5 sec, something went wrong.
+	 */
+	*is->is_flushva[0] = 1;
+	*is->is_flushva[1] = 1;
+	membar(StoreStore);
+	for (i = 0; i < 2; i++) {
+		if (is->is_sb[i] != 0) {
+			*is->is_flushva[i] = 0;
+			IOMMU_WRITE8(is, is_sb[i], ISR_FLUSHSYNC,
+			    is->is_flushpa[i]);
+		}
+	}
+
+	microuptime(&cur);
+	end.tv_sec = 0;
+	/*
+	 * 0.5s is the recommended timeout from the U2S manual.  The actual
+	 * time required should be smaller by at least a factor of 1000.
+	 * We have no choice but to busy-wait.
+	 */
+	end.tv_usec = 500000;
+	timevaladd(&end, &cur);
+
+	while ((!*is->is_flushva[0] || !*is->is_flushva[1]) &&
+	    timevalcmp(&cur, &end, <=))
+		microuptime(&cur);
+
+	if (!*is->is_flushva[0] || !*is->is_flushva[1]) {
+		panic("%s: flush timeout %ld, %ld at %#lx", __func__,
+		    *is->is_flushva[0], *is->is_flushva[1], is->is_flushpa[0]);
+	}
+
+	return (1);
+}
+
+/* Determine whether we may enable streaming on a mapping. */
+static __inline int
+iommu_use_streaming(struct iommu_state *is, bus_dmamap_t map, bus_size_t size)
+{
+
+	return (size >= IOMMU_STREAM_THRESH && IOMMU_HAS_SB(is) &&
+	    (map->dm_flags & DMF_COHERENT) == 0);
+}
+
+/*
+ * Allocate DVMA virtual memory for a map.  The map may not be on a queue,
+ * so that it can be freely modified.
+ */
+static int
+iommu_dvma_valloc(bus_dma_tag_t t, struct iommu_state *is, bus_dmamap_t map,
+    bus_size_t size)
+{
+	struct resource *res;
+	struct bus_dmamap_res *bdr;
+	bus_size_t align, sgsize;
+
+	KASSERT(!map->dm_onq, ("%s: map on queue!", __func__));
+	if ((bdr = malloc(sizeof(*bdr), M_IOMMU, M_NOWAIT)) == NULL)
+		return (EAGAIN);
+	/*
+	 * If a boundary is specified, a map cannot be larger than it; however
+	 * we do not clip currently, as that does not play well with the lazy
+	 * allocation code.
+	 * Alignment to a page boundary is always enforced.
+	 */
+	align = (t->dt_alignment + IO_PAGE_MASK) >> IO_PAGE_SHIFT;
+	sgsize = round_io_page(size) >> IO_PAGE_SHIFT;
+	if (t->dt_boundary > 0 && t->dt_boundary < IO_PAGE_SIZE)
+		panic("%s: illegal boundary specified", __func__);
+	res = rman_reserve_resource_bound(&is->is_dvma_rman, 0L,
+	    t->dt_lowaddr >> IO_PAGE_SHIFT, sgsize,
+	    t->dt_boundary >> IO_PAGE_SHIFT,
+	    RF_ACTIVE | rman_make_alignment_flags(align), NULL);
+	if (res == NULL) {
+		free(bdr, M_IOMMU);
+		return (ENOMEM);
+	}
+
+	bdr->dr_res = res;
+	bdr->dr_used = 0;
+	SLIST_INSERT_HEAD(&map->dm_reslist, bdr, dr_link);
+	return (0);
+}
+
+/* Unload the map and mark all resources as unused, but do not free them. */
+static void
+iommu_dvmamap_vunload(struct iommu_state *is, bus_dmamap_t map)
+{
+	struct bus_dmamap_res *r;
+	int streamed = 0;
+
+	IS_LOCK_ASSERT(is);	/* for iommu_strbuf_sync() below */
+	SLIST_FOREACH(r, &map->dm_reslist, dr_link) {
+		streamed |= iommu_remove(is, BDR_START(r), r->dr_used);
+		r->dr_used = 0;
+	}
+	if (streamed)
+		iommu_strbuf_sync(is);
+}
+
+/* Free a DVMA virtual memory resource. */
+static __inline void
+iommu_dvma_vfree_res(bus_dmamap_t map, struct bus_dmamap_res *r)
+{
+
+	KASSERT(r->dr_used == 0, ("%s: resource busy!", __func__));
+	if (r->dr_res != NULL && rman_release_resource(r->dr_res) != 0)
+		printf("warning: DVMA space lost\n");
+	SLIST_REMOVE(&map->dm_reslist, r, bus_dmamap_res, dr_link);
+	free(r, M_IOMMU);
+}
+
+/* Free all DVMA virtual memory for a map. */
+static void
+iommu_dvma_vfree(struct iommu_state *is, bus_dmamap_t map)
+{
+
+	IS_LOCK(is);
+	iommu_map_remq(is, map);
+	iommu_dvmamap_vunload(is, map);
+	IS_UNLOCK(is);
+	while (!SLIST_EMPTY(&map->dm_reslist))
+		iommu_dvma_vfree_res(map, SLIST_FIRST(&map->dm_reslist));
+}
+
+/* Prune a map, freeing all unused DVMA resources. */
+static bus_size_t
+iommu_dvma_vprune(struct iommu_state *is, bus_dmamap_t map)
+{
+	struct bus_dmamap_res *r, *n;
+	bus_size_t freed = 0;
+
+	IS_LOCK_ASSERT(is);
+	for (r = SLIST_FIRST(&map->dm_reslist); r != NULL; r = n) {
+		n = SLIST_NEXT(r, dr_link);
+		if (r->dr_used == 0) {
+			freed += BDR_SIZE(r);
+			iommu_dvma_vfree_res(map, r);
+		}
+	}
+	if (SLIST_EMPTY(&map->dm_reslist))
+		iommu_map_remq(is, map);
+	return (freed);
+}
+
+/*
+ * Try to find a suitably-sized (and if requested, -aligned) slab of DVMA
+ * memory with IO page offset voffs.
+ */
+static bus_addr_t
+iommu_dvma_vfindseg(bus_dmamap_t map, vm_offset_t voffs, bus_size_t size,
+    bus_addr_t amask)
+{
+	struct bus_dmamap_res *r;
+	bus_addr_t dvmaddr, dvmend;
+
+	KASSERT(!map->dm_onq, ("%s: map on queue!", __func__));
+	SLIST_FOREACH(r, &map->dm_reslist, dr_link) {
+		dvmaddr = round_io_page(BDR_START(r) + r->dr_used);
+		/* Alignment can only work with voffs == 0. */
+		dvmaddr = (dvmaddr + amask) & ~amask;
+		dvmaddr += voffs;
+		dvmend = dvmaddr + size;
+		if (dvmend <= BDR_END(r)) {
+			r->dr_used = dvmend - BDR_START(r);
+			return (dvmaddr);
+		}
+	}
+	return (0);
+}
+
+/*
+ * Try to find or allocate a slab of DVMA space; see above.
+ */
+static int
+iommu_dvma_vallocseg(bus_dma_tag_t dt, struct iommu_state *is, bus_dmamap_t map,
+    vm_offset_t voffs, bus_size_t size, bus_addr_t amask, bus_addr_t *addr)
+{
+	bus_dmamap_t tm, last;
+	bus_addr_t dvmaddr, freed;
+	int error, complete = 0;
+
+	dvmaddr = iommu_dvma_vfindseg(map, voffs, size, amask);
+
+	/* Need to allocate. */
+	if (dvmaddr == 0) {
+		while ((error = iommu_dvma_valloc(dt, is, map,
+			voffs + size)) == ENOMEM && !complete) {
+			/*
+			 * Free the allocated DVMA of a few maps until
+			 * the required size is reached. This is an
+			 * approximation to not have to call the allocation
+			 * function too often; most likely one free run
+			 * will not suffice if not one map was large enough
+			 * itself due to fragmentation.
+			 */
+			IS_LOCK(is);
+			freed = 0;
+			last = TAILQ_LAST(&is->is_maplruq, iommu_maplruq_head);
+			do {
+				tm = TAILQ_FIRST(&is->is_maplruq);
+				complete = tm == last;
+				if (tm == NULL)
+					break;
+				freed += iommu_dvma_vprune(is, tm);
+				/* Move to the end. */
+				iommu_map_insq(is, tm);
+			} while (freed < size && !complete);
+			IS_UNLOCK(is);
+		}
+		if (error != 0)
+			return (error);
+		dvmaddr = iommu_dvma_vfindseg(map, voffs, size, amask);
+		KASSERT(dvmaddr != 0, ("%s: allocation failed unexpectedly!",
+		    __func__));
+	}
+	*addr = dvmaddr;
+	return (0);
+}
+
+static int
+iommu_dvmamem_alloc(bus_dma_tag_t dt, void **vaddr, int flags,
+    bus_dmamap_t *mapp)
+{
+	struct iommu_state *is = dt->dt_cookie;
+	int error, mflags;
+
+	/*
+	 * XXX: This will break for 32 bit transfers on machines with more
+	 * than is->is_pmaxaddr memory.
+	 */
+	if ((error = sparc64_dma_alloc_map(dt, mapp)) != 0)
+		return (error);
+
+	if ((flags & BUS_DMA_NOWAIT) != 0)
+		mflags = M_NOWAIT;
+	else
+		mflags = M_WAITOK;
+	if ((flags & BUS_DMA_ZERO) != 0)
+		mflags |= M_ZERO;
+
+	if ((*vaddr = malloc(dt->dt_maxsize, M_IOMMU, mflags)) == NULL) {
+		error = ENOMEM;
+		sparc64_dma_free_map(dt, *mapp);
+		return (error);
+	}
+	if ((flags & BUS_DMA_COHERENT) != 0)
+		(*mapp)->dm_flags |= DMF_COHERENT;
+	/*
+	 * Try to preallocate DVMA space.  If this fails, it is retried at
+	 * load time.
+	 */
+	iommu_dvma_valloc(dt, is, *mapp, IOMMU_SIZE_ROUNDUP(dt->dt_maxsize));
+	IS_LOCK(is);
+	iommu_map_insq(is, *mapp);
+	IS_UNLOCK(is);
+	return (0);
+}
+
+static void
+iommu_dvmamem_free(bus_dma_tag_t dt, void *vaddr, bus_dmamap_t map)
+{
+	struct iommu_state *is = dt->dt_cookie;
+
+	iommu_dvma_vfree(is, map);
+	sparc64_dma_free_map(dt, map);
+	free(vaddr, M_IOMMU);
+}
+
+static int
+iommu_dvmamap_create(bus_dma_tag_t dt, int flags, bus_dmamap_t *mapp)
+{
+	struct iommu_state *is = dt->dt_cookie;
+	bus_size_t totsz, presz, currsz;
+	int error, i, maxpre;
+
+	if ((error = sparc64_dma_alloc_map(dt, mapp)) != 0)
+		return (error);
+	if ((flags & BUS_DMA_COHERENT) != 0)
+		(*mapp)->dm_flags |= DMF_COHERENT;
+	/*
+	 * Preallocate DVMA space; if this fails now, it is retried at load
+	 * time.  Through bus_dmamap_load_mbuf() and bus_dmamap_load_uio(),
+	 * it is possible to have multiple discontiguous segments in a single
+	 * map, which is handled by allocating additional resources, instead
+	 * of increasing the size, to avoid fragmentation.
+	 * Clamp preallocation to IOMMU_MAX_PRE.  In some situations we can
+	 * handle more; that case is handled by reallocating at map load time.
+	 */
+	totsz = ulmin(IOMMU_SIZE_ROUNDUP(dt->dt_maxsize), IOMMU_MAX_PRE);
+	error = iommu_dvma_valloc(dt, is, *mapp, totsz);
+	if (error != 0)
+		return (0);
+	/*
+	 * Try to be smart about preallocating some additional segments if
+	 * needed.
+	 */
+	maxpre = imin(dt->dt_nsegments, IOMMU_MAX_PRE_SEG);
+	presz = dt->dt_maxsize / maxpre;
+	for (i = 1; i < maxpre && totsz < IOMMU_MAX_PRE; i++) {
+		currsz = round_io_page(ulmin(presz, IOMMU_MAX_PRE - totsz));
+		error = iommu_dvma_valloc(dt, is, *mapp, currsz);
+		if (error != 0)
+			break;
+		totsz += currsz;
+	}
+	IS_LOCK(is);
+	iommu_map_insq(is, *mapp);
+	IS_UNLOCK(is);
+	return (0);
+}
+
+static int
+iommu_dvmamap_destroy(bus_dma_tag_t dt, bus_dmamap_t map)
+{
+	struct iommu_state *is = dt->dt_cookie;
+
+	iommu_dvma_vfree(is, map);
+	sparc64_dma_free_map(dt, map);
+	return (0);
+}
+
+/*
+ * Utility function to load a physical buffer.  segp contains
+ * the starting segment on entrace, and the ending segment on exit.
+ */
+static int
+iommu_dvmamap_load_phys(bus_dma_tag_t dt, bus_dmamap_t map, vm_paddr_t buf,
+    bus_size_t buflen, int flags, bus_dma_segment_t *segs, int *segp)
+{
+	bus_addr_t amask, dvmaddr, dvmoffs;
+	bus_size_t sgsize, esize;
+	struct iommu_state *is;
+	vm_offset_t voffs;
+	vm_paddr_t curaddr;
+	int error, firstpg, sgcnt;
+	u_int slot;
+
+	is = dt->dt_cookie;
+	if (*segp == -1) {
+		if ((map->dm_flags & DMF_LOADED) != 0) {
+#ifdef DIAGNOSTIC
+			printf("%s: map still in use\n", __func__);
+#endif
+			bus_dmamap_unload(dt, map);
+		}
+
+		/*
+		 * Make sure that the map is not on a queue so that the
+		 * resource list may be safely accessed and modified without
+		 * needing the lock to cover the whole operation.
+		 */
+		IS_LOCK(is);
+		iommu_map_remq(is, map);
+		IS_UNLOCK(is);
+
+		amask = dt->dt_alignment - 1;
+	} else
+		amask = 0;
+	KASSERT(buflen != 0, ("%s: buflen == 0!", __func__));
+	if (buflen > dt->dt_maxsize)
+		return (EINVAL);
+
+	if (segs == NULL)
+		segs = dt->dt_segments;
+
+	voffs = buf & IO_PAGE_MASK;
+
+	/* Try to find a slab that is large enough. */
+	error = iommu_dvma_vallocseg(dt, is, map, voffs, buflen, amask,
+	    &dvmaddr);
+	if (error != 0)
+		return (error);
+
+	sgcnt = *segp;
+	firstpg = 1;
+	map->dm_flags &= ~DMF_STREAMED;
+	map->dm_flags |= iommu_use_streaming(is, map, buflen) != 0 ?
+	    DMF_STREAMED : 0;
+	for (; buflen > 0; ) {
+		curaddr = buf;
+
+		/*
+		 * Compute the segment size, and adjust counts.
+		 */
+		sgsize = IO_PAGE_SIZE - ((u_long)buf & IO_PAGE_MASK);
+		if (buflen < sgsize)
+			sgsize = buflen;
+
+		buflen -= sgsize;
+		buf += sgsize;
+
+		dvmoffs = trunc_io_page(dvmaddr);
+		iommu_enter(is, dvmoffs, trunc_io_page(curaddr),
+		    (map->dm_flags & DMF_STREAMED) != 0, flags);
+		if ((is->is_flags & IOMMU_FLUSH_CACHE) != 0) {
+			slot = IOTSBSLOT(dvmoffs);
+			if (buflen <= 0 || slot % 8 == 7)
+				IOMMU_WRITE8(is, is_iommu, IMR_CACHE_FLUSH,
+				    is->is_ptsb + slot * 8);
+		}
+
+		/*
+		 * Chop the chunk up into segments of at most maxsegsz, but try
+		 * to fill each segment as well as possible.
+		 */
+		if (!firstpg) {
+			esize = ulmin(sgsize,
+			    dt->dt_maxsegsz - segs[sgcnt].ds_len);
+			segs[sgcnt].ds_len += esize;
+			sgsize -= esize;
+			dvmaddr += esize;
+		}
+		while (sgsize > 0) {
+			sgcnt++;
+			if (sgcnt >= dt->dt_nsegments)
+				return (EFBIG);
+			/*
+			 * No extra alignment here - the common practice in
+			 * the busdma code seems to be that only the first
+			 * segment needs to satisfy the alignment constraints
+			 * (and that only for bus_dmamem_alloc()ed maps).
+			 * It is assumed that such tags have maxsegsize >=
+			 * maxsize.
+			 */
+			esize = ulmin(sgsize, dt->dt_maxsegsz);
+			segs[sgcnt].ds_addr = dvmaddr;
+			segs[sgcnt].ds_len = esize;
+			sgsize -= esize;
+			dvmaddr += esize;
+		}
+
+		firstpg = 0;
+	}
+	*segp = sgcnt;
+	return (0);
+}
+
+/*
+ * IOMMU DVMA operations, common to PCI and SBus
+ */
+static int
+iommu_dvmamap_load_buffer(bus_dma_tag_t dt, bus_dmamap_t map, void *buf,
+    bus_size_t buflen, pmap_t pmap, int flags, bus_dma_segment_t *segs,
+    int *segp)
+{
+	bus_addr_t amask, dvmaddr, dvmoffs;
+	bus_size_t sgsize, esize;
+	struct iommu_state *is;
+	vm_offset_t vaddr, voffs;
+	vm_paddr_t curaddr;
+	int error, firstpg, sgcnt;
+	u_int slot;
+
+	is = dt->dt_cookie;
+	if (*segp == -1) {
+		if ((map->dm_flags & DMF_LOADED) != 0) {
+#ifdef DIAGNOSTIC
+			printf("%s: map still in use\n", __func__);
+#endif
+			bus_dmamap_unload(dt, map);
+		}
+
+		/*
+		 * Make sure that the map is not on a queue so that the
+		 * resource list may be safely accessed and modified without
+		 * needing the lock to cover the whole operation.
+		 */
+		IS_LOCK(is);
+		iommu_map_remq(is, map);
+		IS_UNLOCK(is);
+
+		amask = dt->dt_alignment - 1;
+	} else
+		amask = 0;
+	KASSERT(buflen != 0, ("%s: buflen == 0!", __func__));
+	if (buflen > dt->dt_maxsize)
+		return (EINVAL);
+
+	if (segs == NULL)
+		segs = dt->dt_segments;
+
+	vaddr = (vm_offset_t)buf;
+	voffs = vaddr & IO_PAGE_MASK;
+
+	/* Try to find a slab that is large enough. */
+	error = iommu_dvma_vallocseg(dt, is, map, voffs, buflen, amask,
+	    &dvmaddr);
+	if (error != 0)
+		return (error);
+
+	sgcnt = *segp;
+	firstpg = 1;
+	map->dm_flags &= ~DMF_STREAMED;
+	map->dm_flags |= iommu_use_streaming(is, map, buflen) != 0 ?
+	    DMF_STREAMED : 0;
+	for (; buflen > 0; ) {
+		/*
+		 * Get the physical address for this page.
+		 */
+		if (pmap == kernel_pmap)
+			curaddr = pmap_kextract(vaddr);
+		else
+			curaddr = pmap_extract(pmap, vaddr);
+
+		/*
+		 * Compute the segment size, and adjust counts.
+		 */
+		sgsize = IO_PAGE_SIZE - ((u_long)vaddr & IO_PAGE_MASK);
+		if (buflen < sgsize)
+			sgsize = buflen;
+
+		buflen -= sgsize;
+		vaddr += sgsize;
+
+		dvmoffs = trunc_io_page(dvmaddr);
+		iommu_enter(is, dvmoffs, trunc_io_page(curaddr),
+		    (map->dm_flags & DMF_STREAMED) != 0, flags);
+		if ((is->is_flags & IOMMU_FLUSH_CACHE) != 0) {
+			slot = IOTSBSLOT(dvmoffs);
+			if (buflen <= 0 || slot % 8 == 7)
+				IOMMU_WRITE8(is, is_iommu, IMR_CACHE_FLUSH,
+				    is->is_ptsb + slot * 8);
+		}
+
+		/*
+		 * Chop the chunk up into segments of at most maxsegsz, but try
+		 * to fill each segment as well as possible.
+		 */
+		if (!firstpg) {
+			esize = ulmin(sgsize,
+			    dt->dt_maxsegsz - segs[sgcnt].ds_len);
+			segs[sgcnt].ds_len += esize;
+			sgsize -= esize;
+			dvmaddr += esize;
+		}
+		while (sgsize > 0) {
+			sgcnt++;
+			if (sgcnt >= dt->dt_nsegments)
+				return (EFBIG);
+			/*
+			 * No extra alignment here - the common practice in
+			 * the busdma code seems to be that only the first
+			 * segment needs to satisfy the alignment constraints
+			 * (and that only for bus_dmamem_alloc()ed maps).
+			 * It is assumed that such tags have maxsegsize >=
+			 * maxsize.
+			 */
+			esize = ulmin(sgsize, dt->dt_maxsegsz);
+			segs[sgcnt].ds_addr = dvmaddr;
+			segs[sgcnt].ds_len = esize;
+			sgsize -= esize;
+			dvmaddr += esize;
+		}
+
+		firstpg = 0;
+	}
+	*segp = sgcnt;
+	return (0);
+}
+
+static void
+iommu_dvmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map,
+    struct memdesc *mem, bus_dmamap_callback_t *callback, void *callback_arg)
+{
+}
+
+static bus_dma_segment_t *
+iommu_dvmamap_complete(bus_dma_tag_t dt, bus_dmamap_t map,
+    bus_dma_segment_t *segs, int nsegs, int error)
+{
+	struct iommu_state *is = dt->dt_cookie;
+
+	IS_LOCK(is);
+	iommu_map_insq(is, map);
+	if (error != 0) {
+		iommu_dvmamap_vunload(is, map);
+		IS_UNLOCK(is);
+	} else {
+		IS_UNLOCK(is);
+		map->dm_flags |= DMF_LOADED;
+	}
+	if (segs == NULL)
+		segs = dt->dt_segments;
+	return (segs);
+}
+
+static void
+iommu_dvmamap_unload(bus_dma_tag_t dt, bus_dmamap_t map)
+{
+	struct iommu_state *is = dt->dt_cookie;
+
+	if ((map->dm_flags & DMF_LOADED) == 0)
+		return;
+	IS_LOCK(is);
+	iommu_dvmamap_vunload(is, map);
+	iommu_map_insq(is, map);
+	IS_UNLOCK(is);
+	map->dm_flags &= ~DMF_LOADED;
+}
+
+static void
+iommu_dvmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
+{
+	struct iommu_state *is = dt->dt_cookie;
+	struct bus_dmamap_res *r;
+	vm_offset_t va;
+	vm_size_t len;
+	int streamed = 0;
+
+	if ((map->dm_flags & DMF_LOADED) == 0)
+		return;
+	if ((map->dm_flags & DMF_STREAMED) != 0 &&
+	    ((op & BUS_DMASYNC_POSTREAD) != 0 ||
+	    (op & BUS_DMASYNC_PREWRITE) != 0)) {
+		IS_LOCK(is);
+		SLIST_FOREACH(r, &map->dm_reslist, dr_link) {
+			va = (vm_offset_t)BDR_START(r);
+			len = r->dr_used;
+			/*
+			 * If we have a streaming buffer, flush it here
+			 * first.
+			 */
+			while (len > 0) {
+				if ((IOMMU_GET_TTE(is, va) &
+				    IOTTE_STREAM) != 0) {
+					streamed = 1;
+					iommu_strbuf_flush(is, va);
+				}
+				len -= ulmin(len, IO_PAGE_SIZE);
+				va += IO_PAGE_SIZE;
+			}
+		}
+		if (streamed)
+			iommu_strbuf_sync(is);
+		IS_UNLOCK(is);
+	}
+	if ((op & BUS_DMASYNC_PREWRITE) != 0)
+		membar(Sync);
+}
+
+#ifdef IOMMU_DIAG
+
+/*
+ * Perform an IOMMU diagnostic access and print the tag belonging to va.
+ */
+static void
+iommu_diag(struct iommu_state *is, vm_offset_t va)
+{
+	int i;
+	uint64_t data, tag;
+
+	if ((is->is_flags & IOMMU_FIRE) != 0)
+		return;
+	IS_LOCK_ASSERT(is);
+	IOMMU_WRITE8(is, is_dva, 0, trunc_io_page(va));
+	membar(StoreStore | StoreLoad);
+	printf("%s: tte entry %#lx", __func__, IOMMU_GET_TTE(is, va));
+	if (is->is_dtcmp != 0) {
+		printf(", tag compare register is %#lx\n",
+		    IOMMU_READ8(is, is_dtcmp, 0));
+	} else
+		printf("\n");
+	for (i = 0; i < 16; i++) {
+		tag = IOMMU_READ8(is, is_dtag, i * 8);
+		data = IOMMU_READ8(is, is_ddram, i * 8);
+		printf("%s: tag %d: %#lx, vpn %#lx, err %lx; "
+		    "data %#lx, pa %#lx, v %d, c %d\n", __func__, i,
+		    tag, (tag & IOMMU_DTAG_VPNMASK) << IOMMU_DTAG_VPNSHIFT,
+		    (tag & IOMMU_DTAG_ERRMASK) >> IOMMU_DTAG_ERRSHIFT, data,
+		    (data & IOMMU_DDATA_PGMASK) << IOMMU_DDATA_PGSHIFT,
+		    (data & IOMMU_DDATA_V) != 0, (data & IOMMU_DDATA_C) != 0);
+	}
+}
+
+#endif /* IOMMU_DIAG */
+
+struct bus_dma_methods iommu_dma_methods = {
+	iommu_dvmamap_create,
+	iommu_dvmamap_destroy,
+	iommu_dvmamap_load_phys,
+	iommu_dvmamap_load_buffer,
+	iommu_dvmamap_waitok,
+	iommu_dvmamap_complete,
+	iommu_dvmamap_unload,
+	iommu_dvmamap_sync,
+	iommu_dvmamem_alloc,
+	iommu_dvmamem_free,
+};


Property changes on: trunk/sys/sparc64/sparc64/iommu.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/jbusppm.c
===================================================================
--- trunk/sys/sparc64/sparc64/jbusppm.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/jbusppm.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,231 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/jbusppm.c 227848 2011-11-22 21:55:40Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#if 1
+#include <sparc64/pci/ofw_pci.h>
+#endif
+
+#define	JBUSPPM_NREG	2
+
+#define	JBUSPPM_DEVID	0
+#define	JBUSPPM_ESTAR	1
+
+#define	JBUSPPM_DEVID_JID		0x00
+#define	JBUSPPM_DEVID_JID_MASTER	0x00040000
+
+#define	JBUSPPM_ESTAR_CTRL		0x00
+#define	JBUSPPM_ESTAR_CTRL_1		0x00000001
+#define	JBUSPPM_ESTAR_CTRL_2		0x00000002
+#define	JBUSPPM_ESTAR_CTRL_32		0x00000020
+#define	JBUSPPM_ESTAR_CTRL_MASK						\
+	(JBUSPPM_ESTAR_CTRL_1 | JBUSPPM_ESTAR_CTRL_2 | JBUSPPM_ESTAR_CTRL_32)
+#define	JBUSPPM_ESTAR_JCHNG		0x08
+#define	JBUSPPM_ESTAR_JCHNG_DELAY_MASK	0x00000007
+#define	JBUSPPM_ESTAR_JCHNG_START	0x00000010
+#define	JBUSPPM_ESTAR_JCHNG_OCCURED	0x00000018
+
+struct jbusppm_softc {
+	struct resource		*sc_res[JBUSPPM_NREG];
+	bus_space_tag_t		sc_bt[JBUSPPM_NREG];
+	bus_space_handle_t	sc_bh[JBUSPPM_NREG];
+};
+
+#define	JBUSPPM_READ(sc, reg, off)					\
+	bus_space_read_8((sc)->sc_bt[(reg)], (sc)->sc_bh[(reg)], (off))
+#define	JBUSPPM_WRITE(sc, reg, off, val)				\
+	bus_space_write_8((sc)->sc_bt[(reg)], (sc)->sc_bh[(reg)], (off), (val))
+
+static device_probe_t jbusppm_probe;
+static device_attach_t jbusppm_attach;
+
+static device_method_t jbusppm_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		jbusppm_probe),
+	DEVMETHOD(device_attach,	jbusppm_attach),
+
+	DEVMETHOD_END
+};
+
+static devclass_t jbusppm_devclass;
+
+DEFINE_CLASS_0(jbusppm, jbusppm_driver, jbusppm_methods,
+    sizeof(struct jbusppm_softc));
+DRIVER_MODULE(jbusppm, nexus, jbusppm_driver, jbusppm_devclass, 0, 0);
+
+static int
+jbusppm_probe(device_t dev)
+{
+	const char* compat;
+
+	compat = ofw_bus_get_compat(dev);
+	if (compat != NULL && strcmp(ofw_bus_get_name(dev), "ppm") == 0 &&
+	    strcmp(compat, "jbus-ppm") == 0) {
+		device_set_desc(dev, "JBus power management");
+		return (BUS_PROBE_DEFAULT);
+	}
+	return (ENXIO);
+}
+
+static int
+jbusppm_attach(device_t dev)
+{
+	struct jbusppm_softc *sc;
+	int i, rid;
+#if 1
+	device_t *children, tomatillo;
+	u_long tcount, tstart, jcount, jstart;
+	int j, nchildren;
+#endif
+
+	sc = device_get_softc(dev);
+	for (i = JBUSPPM_DEVID; i <= JBUSPPM_ESTAR; i++) {
+		rid = i;
+		/*
+		 * The JBUSPPM_ESTAR resources is shared with that of the
+		 * Tomatillo bus A controller configuration register bank.
+		 */
+#if 0
+		sc->sc_res[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+		    &rid, (i == JBUSPPM_ESTAR ? RF_SHAREABLE : 0) | RF_ACTIVE);
+		if (sc->sc_res[i] == NULL) {
+			device_printf(dev,
+			    "could not allocate resource %d\n", i);
+			goto fail;
+		}
+		sc->sc_bt[i] = rman_get_bustag(sc->sc_res[i]);
+		sc->sc_bh[i] = rman_get_bushandle(sc->sc_res[i]);
+#else
+		/*
+		 * Workaround for the fact that rman(9) only allows to
+		 * share resources of the same size.
+		 */
+		if (i == JBUSPPM_ESTAR) {
+			if (bus_get_resource(dev, SYS_RES_MEMORY, i, &jstart,
+			    &jcount) != 0) {
+				device_printf(dev,
+				    "could not determine Estar resource\n");
+				goto fail;
+			}
+			if (device_get_children(device_get_parent(dev),
+			    &children, &nchildren) != 0) {
+				device_printf(dev, "could not get children\n");
+				goto fail;
+			}
+			tomatillo = NULL;
+			for (j = 0; j < nchildren; j++) {
+				if (ofw_bus_get_type(children[j]) != NULL &&
+				    strcmp(ofw_bus_get_type(children[j]),
+				    OFW_TYPE_PCI) == 0 &&
+				    ofw_bus_get_compat(children[j]) != NULL &&
+				    strcmp(ofw_bus_get_compat(children[j]),
+				    "pci108e,a801") == 0 &&
+				    ((bus_get_resource_start(children[j],
+				    SYS_RES_MEMORY, 0) >> 20) & 1) == 0) {
+					tomatillo = children[j];
+					break;
+				}
+			}
+			free(children, M_TEMP);
+			if (tomatillo == NULL) {
+				device_printf(dev,
+				    "could not find Tomatillo\n");
+				goto fail;
+			}
+			if (bus_get_resource(tomatillo, SYS_RES_MEMORY, 1,
+			    &tstart, &tcount) != 0) {
+				device_printf(dev,
+				    "could not determine Tomatillo "
+				    "resource\n");
+				goto fail;
+			}
+			sc->sc_res[i] = bus_alloc_resource(dev, SYS_RES_MEMORY,
+			    &rid, tstart, tstart + tcount - 1, tcount,
+			    RF_SHAREABLE | RF_ACTIVE);
+		} else
+			sc->sc_res[i] = bus_alloc_resource_any(dev,
+			    SYS_RES_MEMORY, &rid, RF_ACTIVE);
+		if (sc->sc_res[i] == NULL) {
+			device_printf(dev,
+			    "could not allocate resource %d\n", i);
+			goto fail;
+		}
+		sc->sc_bt[i] = rman_get_bustag(sc->sc_res[i]);
+		sc->sc_bh[i] = rman_get_bushandle(sc->sc_res[i]);
+		if (i == JBUSPPM_ESTAR)
+			bus_space_subregion(sc->sc_bt[i], sc->sc_bh[i],
+			    jstart - tstart, jcount, &sc->sc_bh[i]);
+#endif
+	}
+
+	if (bootverbose) {
+		if ((JBUSPPM_READ(sc, JBUSPPM_DEVID, JBUSPPM_DEVID_JID) &
+		    JBUSPPM_DEVID_JID_MASTER) != 0)
+			device_printf(dev, "master I/O bridge\n");
+		device_printf(dev, "running at ");
+		switch (JBUSPPM_READ(sc, JBUSPPM_ESTAR, JBUSPPM_ESTAR_CTRL) &
+		    JBUSPPM_ESTAR_CTRL_MASK) {
+		case JBUSPPM_ESTAR_CTRL_1:
+			printf("full");
+			break;
+		case JBUSPPM_ESTAR_CTRL_2:
+			printf("half");
+			break;
+		case JBUSPPM_ESTAR_CTRL_32:
+			printf("1/32");
+			break;
+		default:
+			printf("unknown");
+			break;
+		}
+		printf(" speed\n");
+	}
+
+	return (0);
+
+ fail:
+	for (i = JBUSPPM_DEVID; i <= JBUSPPM_ESTAR && sc->sc_res[i] != NULL;
+	    i++)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    rman_get_rid(sc->sc_res[i]), sc->sc_res[i]);
+	return (ENXIO);
+}


Property changes on: trunk/sys/sparc64/sparc64/jbusppm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/locore.S
===================================================================
--- trunk/sys/sparc64/sparc64/locore.S	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/locore.S	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,149 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/locore.S 207248 2010-04-26 20:19:49Z marius $");
+
+#include <machine/asi.h>
+#include <machine/asmacros.h>
+#include <machine/intr_machdep.h>
+#include <machine/pstate.h>
+#include <machine/wstate.h>
+
+#include "assym.s"
+
+	.register %g2,#ignore
+
+	.globl	kernbase
+	.set	kernbase, KERNBASE
+
+/*
+ * void _start(caddr_t metadata, u_long o1, u_long o2, u_long o3,
+ *     u_long ofw_vec)
+ */
+ENTRY(btext)
+ENTRY(_start)
+	/*
+	 * Initialize misc. state to known values: interrupts disabled, normal
+	 * globals, windows flushed (cr = 0, cs = nwindows - 1), PIL_TICK and
+	 * floating point disabled.
+	 * Note that some firmware versions don't implement a clean window
+	 * trap handler so we unfortunately can't clear the windows by setting
+	 * %cleanwin to zero here.
+	 */
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+	flushw
+	wrpr	%g0, PIL_TICK, %pil
+	wr	%g0, 0, %fprs
+
+	/*
+	 * Get onto our per-CPU panic stack, which precedes the struct pcpu in
+	 * the per-CPU page.
+	 */
+	SET(pcpu0 + (PCPU_PAGES * PAGE_SIZE) - PC_SIZEOF, %l1, %l0)
+	sub	%l0, SPOFF + CCFSZ, %sp
+
+	/*
+	 * Do initial bootstrap to setup pmap and thread0.
+	 */
+	call	sparc64_init
+	 nop
+
+	/*
+	 * Get onto thread0's kstack.
+	 */
+	sub	PCB_REG, SPOFF + CCFSZ, %sp
+
+	/*
+	 * And away we go.  This doesn't return.
+	 */
+	call	mi_startup
+	 nop
+	sir
+	! NOTREACHED
+END(_start)
+
+/*
+ * void cpu_setregs(struct pcpu *pc)
+ */
+ENTRY(cpu_setregs)
+	ldx	[%o0 + PC_CURPCB], %o1
+
+	/*
+	 * Ensure we are on normal globals.
+	 */
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	/*
+	 * Normal %g6 points to the current thread's PCB, and %g7 points to
+	 * the per-CPU data structure.
+	 */
+	mov	%o1, PCB_REG
+	mov	%o0, PCPU_REG
+
+	/*
+	 * Switch to alternate globals.
+	 */
+	wrpr	%g0, PSTATE_ALT, %pstate
+
+	/*
+	 * Alternate %g5 points to a per-CPU panic stack, %g6 points to the
+	 * current thread's PCB, and %g7 points to the per-CPU data structure.
+	 */
+	mov	%o0, ASP_REG
+	mov	%o1, PCB_REG
+	mov	%o0, PCPU_REG
+
+	/*
+	 * Switch to interrupt globals.
+	 */
+	wrpr	%g0, PSTATE_INTR, %pstate
+
+	/*
+	 * Interrupt %g7 points to the per-CPU data structure.
+	 */
+	mov	%o0, PCPU_REG
+
+	/*
+	 * Switch to normal globals again.
+	 */
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	/*
+	 * Force trap level 1 and take over the trap table.
+	 */
+	SET(tl0_base, %o2, %o1)
+	SET(tba_taken_over, %o3, %o2)
+	mov	1, %o3
+	wrpr	%g0, WSTATE_KERNEL, %wstate
+	wrpr	%g0, 1, %tl
+	wrpr	%o1, 0, %tba
+	stw	%o3, [%o2]
+
+	retl
+	 nop
+END(cpu_setregs)


Property changes on: trunk/sys/sparc64/sparc64/locore.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,1117 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * Copyright (c) 1992 Terrence R. Lambert.
+ * Copyright (c) 1982, 1987, 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.
+ * 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: @(#)machdep.c	7.4 (Berkeley) 6/3/91
+ *	from: FreeBSD: src/sys/i386/i386/machdep.c,v 1.477 2001/08/27
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/machdep.c 294683 2016-01-24 21:04:06Z ian $");
+
+#include "opt_compat.h"
+#include "opt_ddb.h"
+#include "opt_kstack_pages.h"
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/cons.h>
+#include <sys/eventhandler.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/interrupt.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/msgbuf.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/ptrace.h>
+#include <sys/reboot.h>
+#include <sys/rwlock.h>
+#include <sys/signalvar.h>
+#include <sys/smp.h>
+#include <sys/syscallsubr.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <sys/timetc.h>
+#include <sys/ucontext.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_pager.h>
+#include <vm/vm_param.h>
+
+#include <ddb/ddb.h>
+
+#include <machine/bus.h>
+#include <machine/cache.h>
+#include <machine/cmt.h>
+#include <machine/cpu.h>
+#include <machine/fireplane.h>
+#include <machine/fp.h>
+#include <machine/fsr.h>
+#include <machine/intr_machdep.h>
+#include <machine/jbus.h>
+#include <machine/md_var.h>
+#include <machine/metadata.h>
+#include <machine/ofw_machdep.h>
+#include <machine/ofw_mem.h>
+#include <machine/pcb.h>
+#include <machine/pmap.h>
+#include <machine/pstate.h>
+#include <machine/reg.h>
+#include <machine/sigframe.h>
+#include <machine/smp.h>
+#include <machine/tick.h>
+#include <machine/tlb.h>
+#include <machine/tstate.h>
+#include <machine/upa.h>
+#include <machine/ver.h>
+
+typedef int ofw_vec_t(void *);
+
+#ifdef DDB
+extern vm_offset_t ksym_start, ksym_end;
+#endif
+
+int dtlb_slots;
+int itlb_slots;
+struct tlb_entry *kernel_tlbs;
+int kernel_tlb_slots;
+
+int cold = 1;
+long Maxmem;
+long realmem;
+
+void *dpcpu0;
+char pcpu0[PCPU_PAGES * PAGE_SIZE];
+struct trapframe frame0;
+
+vm_offset_t kstack0;
+vm_paddr_t kstack0_phys;
+
+struct kva_md_info kmi;
+
+u_long ofw_vec;
+u_long ofw_tba;
+u_int tba_taken_over;
+
+char sparc64_model[32];
+
+static int cpu_use_vis = 1;
+
+cpu_block_copy_t *cpu_block_copy;
+cpu_block_zero_t *cpu_block_zero;
+
+static phandle_t find_bsp(phandle_t node, uint32_t bspid, u_int cpu_impl);
+void sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3,
+    ofw_vec_t *vec);
+static void sparc64_shutdown_final(void *dummy, int howto);
+
+static void cpu_startup(void *arg);
+SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
+
+CTASSERT((1 << INT_SHIFT) == sizeof(int));
+CTASSERT((1 << PTR_SHIFT) == sizeof(char *));
+
+CTASSERT(sizeof(struct reg) == 256);
+CTASSERT(sizeof(struct fpreg) == 272);
+CTASSERT(sizeof(struct __mcontext) == 512);
+
+CTASSERT((sizeof(struct pcb) & (64 - 1)) == 0);
+CTASSERT((offsetof(struct pcb, pcb_kfp) & (64 - 1)) == 0);
+CTASSERT((offsetof(struct pcb, pcb_ufp) & (64 - 1)) == 0);
+CTASSERT(sizeof(struct pcb) <= ((KSTACK_PAGES * PAGE_SIZE) / 8));
+
+CTASSERT(sizeof(struct pcpu) <= ((PCPU_PAGES * PAGE_SIZE) / 2));
+
+static void
+cpu_startup(void *arg)
+{
+	vm_paddr_t physsz;
+	int i;
+
+	physsz = 0;
+	for (i = 0; i < sparc64_nmemreg; i++)
+		physsz += sparc64_memreg[i].mr_size;
+	printf("real memory  = %lu (%lu MB)\n", physsz,
+	    physsz / (1024 * 1024));
+	realmem = (long)physsz / PAGE_SIZE;
+
+	vm_ksubmap_init(&kmi);
+
+	bufinit();
+	vm_pager_bufferinit();
+
+	EVENTHANDLER_REGISTER(shutdown_final, sparc64_shutdown_final, NULL,
+	    SHUTDOWN_PRI_LAST);
+
+	printf("avail memory = %lu (%lu MB)\n", cnt.v_free_count * PAGE_SIZE,
+	    cnt.v_free_count / ((1024 * 1024) / PAGE_SIZE));
+
+	if (bootverbose)
+		printf("machine: %s\n", sparc64_model);
+
+	cpu_identify(rdpr(ver), PCPU_GET(clock), curcpu);
+}
+
+void
+cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
+{
+	struct intr_request *ir;
+	int i;
+
+	pcpu->pc_irtail = &pcpu->pc_irhead;
+	for (i = 0; i < IR_FREE; i++) {
+		ir = &pcpu->pc_irpool[i];
+		ir->ir_next = pcpu->pc_irfree;
+		pcpu->pc_irfree = ir;
+	}
+}
+
+void
+spinlock_enter(void)
+{
+	struct thread *td;
+	register_t pil;
+
+	td = curthread;
+	if (td->td_md.md_spinlock_count == 0) {
+		pil = rdpr(pil);
+		wrpr(pil, 0, PIL_TICK);
+		td->td_md.md_spinlock_count = 1;
+		td->td_md.md_saved_pil = pil;
+	} else
+		td->td_md.md_spinlock_count++;
+	critical_enter();
+}
+
+void
+spinlock_exit(void)
+{
+	struct thread *td;
+	register_t pil;
+
+	td = curthread;
+	critical_exit();
+	pil = td->td_md.md_saved_pil;
+	td->td_md.md_spinlock_count--;
+	if (td->td_md.md_spinlock_count == 0)
+		wrpr(pil, pil, 0);
+}
+
+static phandle_t
+find_bsp(phandle_t node, uint32_t bspid, u_int cpu_impl)
+{
+	char type[sizeof("cpu")];
+	phandle_t child;
+	uint32_t portid;
+
+	for (; node != 0; node = OF_peer(node)) {
+		child = OF_child(node);
+		if (child > 0) {
+			child = find_bsp(child, bspid, cpu_impl);
+			if (child > 0)
+				return (child);
+		} else {
+			if (OF_getprop(node, "device_type", type,
+			    sizeof(type)) <= 0)
+				continue;
+			if (strcmp(type, "cpu") != 0)
+				continue;
+			if (OF_getprop(node, cpu_portid_prop(cpu_impl),
+			    &portid, sizeof(portid)) <= 0)
+				continue;
+			if (portid == bspid)
+				return (node);
+		}
+	}
+	return (0);
+}
+
+const char *
+cpu_portid_prop(u_int cpu_impl)
+{
+
+	switch (cpu_impl) {
+	case CPU_IMPL_SPARC64:
+	case CPU_IMPL_SPARC64V:
+	case CPU_IMPL_ULTRASPARCI:
+	case CPU_IMPL_ULTRASPARCII:
+	case CPU_IMPL_ULTRASPARCIIi:
+	case CPU_IMPL_ULTRASPARCIIe:
+		return ("upa-portid");
+	case CPU_IMPL_ULTRASPARCIII:
+	case CPU_IMPL_ULTRASPARCIIIp:
+	case CPU_IMPL_ULTRASPARCIIIi:
+	case CPU_IMPL_ULTRASPARCIIIip:
+		return ("portid");
+	case CPU_IMPL_ULTRASPARCIV:
+	case CPU_IMPL_ULTRASPARCIVp:
+		return ("cpuid");
+	default:
+		return ("");
+	}
+}
+
+uint32_t
+cpu_get_mid(u_int cpu_impl)
+{
+
+	switch (cpu_impl) {
+	case CPU_IMPL_SPARC64:
+	case CPU_IMPL_SPARC64V:
+	case CPU_IMPL_ULTRASPARCI:
+	case CPU_IMPL_ULTRASPARCII:
+	case CPU_IMPL_ULTRASPARCIIi:
+	case CPU_IMPL_ULTRASPARCIIe:
+		return (UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)));
+	case CPU_IMPL_ULTRASPARCIII:
+	case CPU_IMPL_ULTRASPARCIIIp:
+		return (FIREPLANE_CR_GET_AID(ldxa(AA_FIREPLANE_CONFIG,
+		    ASI_FIREPLANE_CONFIG_REG)));
+	case CPU_IMPL_ULTRASPARCIIIi:
+	case CPU_IMPL_ULTRASPARCIIIip:
+		return (JBUS_CR_GET_JID(ldxa(0, ASI_JBUS_CONFIG_REG)));
+	case CPU_IMPL_ULTRASPARCIV:
+	case CPU_IMPL_ULTRASPARCIVp:
+		return (INTR_ID_GET_ID(ldxa(AA_INTR_ID, ASI_INTR_ID)));
+	default:
+		return (0);
+	}
+}
+
+void
+sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
+{
+	char *env;
+	struct pcpu *pc;
+	vm_offset_t end;
+	vm_offset_t va;
+	caddr_t kmdp;
+	phandle_t root;
+	u_int cpu_impl;
+
+	end = 0;
+	kmdp = NULL;
+
+	/*
+	 * Find out what kind of CPU we have first, for anything that changes
+	 * behaviour.
+	 */
+	cpu_impl = VER_IMPL(rdpr(ver));
+
+	/*
+	 * Do CPU-specific initialization.
+	 */
+	if (cpu_impl >= CPU_IMPL_ULTRASPARCIII)
+		cheetah_init(cpu_impl);
+	else if (cpu_impl == CPU_IMPL_SPARC64V)
+		zeus_init(cpu_impl);
+
+	/*
+	 * Clear (S)TICK timer (including NPT).
+	 */
+	tick_clear(cpu_impl);
+
+	/*
+	 * UltraSparc II[e,i] based systems come up with the tick interrupt
+	 * enabled and a handler that resets the tick counter, causing DELAY()
+	 * to not work properly when used early in boot.
+	 * UltraSPARC III based systems come up with the system tick interrupt
+	 * enabled, causing an interrupt storm on startup since they are not
+	 * handled.
+	 */
+	tick_stop(cpu_impl);
+
+	/*
+	 * Set up Open Firmware entry points.
+	 */
+	ofw_tba = rdpr(tba);
+	ofw_vec = (u_long)vec;
+
+	/*
+	 * Parse metadata if present and fetch parameters.  Must be before the
+	 * console is inited so cninit() gets the right value of boothowto.
+	 */
+	if (mdp != NULL) {
+		preload_metadata = mdp;
+		kmdp = preload_search_by_type("elf kernel");
+		if (kmdp != NULL) {
+			boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
+			init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *),
+			    0);
+			end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
+			kernel_tlb_slots = MD_FETCH(kmdp, MODINFOMD_DTLB_SLOTS,
+			    int);
+			kernel_tlbs = (void *)preload_search_info(kmdp,
+			    MODINFO_METADATA | MODINFOMD_DTLB);
+		}
+	}
+
+	init_param1();
+
+	/*
+	 * Initialize Open Firmware (needed for console).
+	 */
+	OF_install(OFW_STD_DIRECT, 0);
+	OF_init(ofw_entry);
+
+	/*
+	 * Prime our per-CPU data page for use.  Note, we are using it for
+	 * our stack, so don't pass the real size (PAGE_SIZE) to pcpu_init
+	 * or it'll zero it out from under us.
+	 */
+	pc = (struct pcpu *)(pcpu0 + (PCPU_PAGES * PAGE_SIZE)) - 1;
+	pcpu_init(pc, 0, sizeof(struct pcpu));
+	pc->pc_addr = (vm_offset_t)pcpu0;
+	pc->pc_impl = cpu_impl;
+	pc->pc_mid = cpu_get_mid(cpu_impl);
+	pc->pc_tlb_ctx = TLB_CTX_USER_MIN;
+	pc->pc_tlb_ctx_min = TLB_CTX_USER_MIN;
+	pc->pc_tlb_ctx_max = TLB_CTX_USER_MAX;
+
+	/*
+	 * Determine the OFW node and frequency of the BSP (and ensure the
+	 * BSP is in the device tree in the first place).
+	 */
+	root = OF_peer(0);
+	pc->pc_node = find_bsp(root, pc->pc_mid, cpu_impl);
+	if (pc->pc_node == 0)
+		OF_panic("%s: cannot find boot CPU node", __func__);
+	if (OF_getprop(pc->pc_node, "clock-frequency", &pc->pc_clock,
+	    sizeof(pc->pc_clock)) <= 0)
+		OF_panic("%s: cannot determine boot CPU clock", __func__);
+
+	/*
+	 * Panic if there is no metadata.  Most likely the kernel was booted
+	 * directly, instead of through loader(8).
+	 */
+	if (mdp == NULL || kmdp == NULL || end == 0 ||
+	    kernel_tlb_slots == 0 || kernel_tlbs == NULL)
+		OF_panic("%s: missing loader metadata.\nThis probably means "
+		    "you are not using loader(8).", __func__);
+
+	/*
+	 * Work around the broken loader behavior of not demapping no
+	 * longer used kernel TLB slots when unloading the kernel or
+	 * modules.
+	 */
+	for (va = KERNBASE + (kernel_tlb_slots - 1) * PAGE_SIZE_4M;
+	    va >= roundup2(end, PAGE_SIZE_4M); va -= PAGE_SIZE_4M) {
+		if (bootverbose)
+			OF_printf("demapping unused kernel TLB slot "
+			    "(va %#lx - %#lx)\n", va, va + PAGE_SIZE_4M - 1);
+		stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE,
+		    ASI_DMMU_DEMAP, 0);
+		stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE,
+		    ASI_IMMU_DEMAP, 0);
+		flush(KERNBASE);
+		kernel_tlb_slots--;
+	}
+
+	/*
+	 * Determine the TLB slot maxima, which are expected to be
+	 * equal across all CPUs.
+	 * NB: for cheetah-class CPUs, these properties only refer
+	 * to the t16s.
+	 */
+	if (OF_getprop(pc->pc_node, "#dtlb-entries", &dtlb_slots,
+	    sizeof(dtlb_slots)) == -1)
+		OF_panic("%s: cannot determine number of dTLB slots",
+		    __func__);
+	if (OF_getprop(pc->pc_node, "#itlb-entries", &itlb_slots,
+	    sizeof(itlb_slots)) == -1)
+		OF_panic("%s: cannot determine number of iTLB slots",
+		    __func__);
+
+	/*
+	 * Initialize and enable the caches.  Note that this may include
+	 * applying workarounds.
+	 */
+	cache_init(pc);
+	cache_enable(cpu_impl);
+	uma_set_align(pc->pc_cache.dc_linesize - 1);
+
+	cpu_block_copy = bcopy;
+	cpu_block_zero = bzero;
+	getenv_int("machdep.use_vis", &cpu_use_vis);
+	if (cpu_use_vis) {
+		switch (cpu_impl) {
+		case CPU_IMPL_SPARC64:
+		case CPU_IMPL_ULTRASPARCI:
+		case CPU_IMPL_ULTRASPARCII:
+		case CPU_IMPL_ULTRASPARCIIi:
+		case CPU_IMPL_ULTRASPARCIIe:
+		case CPU_IMPL_ULTRASPARCIII:	/* NB: we've disabled P$. */
+		case CPU_IMPL_ULTRASPARCIIIp:
+		case CPU_IMPL_ULTRASPARCIIIi:
+		case CPU_IMPL_ULTRASPARCIV:
+		case CPU_IMPL_ULTRASPARCIVp:
+		case CPU_IMPL_ULTRASPARCIIIip:
+			cpu_block_copy = spitfire_block_copy;
+			cpu_block_zero = spitfire_block_zero;
+			break;
+		case CPU_IMPL_SPARC64V:
+			cpu_block_copy = zeus_block_copy;
+			cpu_block_zero = zeus_block_zero;
+			break;
+		}
+	}
+
+#ifdef SMP
+	mp_init();
+#endif
+
+	/*
+	 * Initialize virtual memory and calculate physmem.
+	 */
+	pmap_bootstrap(cpu_impl);
+
+	/*
+	 * Initialize tunables.
+	 */
+	init_param2(physmem);
+	env = getenv("kernelname");
+	if (env != NULL) {
+		strlcpy(kernelname, env, sizeof(kernelname));
+		freeenv(env);
+	}
+
+	/*
+	 * Initialize the interrupt tables.
+	 */
+	intr_init1();
+
+	/*
+	 * Initialize proc0, set kstack0, frame0, curthread and curpcb.
+	 */
+	proc_linkup0(&proc0, &thread0);
+	proc0.p_md.md_sigtramp = NULL;
+	proc0.p_md.md_utrap = NULL;
+	thread0.td_kstack = kstack0;
+	thread0.td_kstack_pages = KSTACK_PAGES;
+	thread0.td_pcb = (struct pcb *)
+	    (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
+	frame0.tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_PRIV;
+	thread0.td_frame = &frame0;
+	pc->pc_curthread = &thread0;
+	pc->pc_curpcb = thread0.td_pcb;
+
+	/*
+	 * Initialize global registers.
+	 */
+	cpu_setregs(pc);
+
+	/*
+	 * Take over the trap table via the PROM.  Using the PROM for this
+	 * is necessary in order to set obp-control-relinquished to true
+	 * within the PROM so obtaining /virtual-memory/translations doesn't
+	 * trigger a fatal reset error or worse things further down the road.
+	 * XXX it should be possible to use this solely instead of writing
+	 * %tba in cpu_setregs().  Doing so causes a hang however.
+	 *
+	 * NB: the low-level console drivers require a working DELAY() and
+	 * some compiler optimizations may cause the curthread accesses of
+	 * mutex(9) to be factored out even if the latter aren't actually
+	 * called.  Both of these require PCPU_REG to be set.  However, we
+	 * can't set PCPU_REG without also taking over the trap table or the
+	 * firmware will overwrite it.
+	 */
+	sun4u_set_traptable(tl0_base);
+
+	/*
+	 * Initialize the dynamic per-CPU area for the BSP and the message
+	 * buffer (after setting the trap table).
+	 */
+	dpcpu_init(dpcpu0, 0);
+	msgbufinit(msgbufp, msgbufsize);
+
+	/*
+	 * Initialize mutexes.
+	 */
+	mutex_init();
+
+	/*
+	 * Initialize console now that we have a reasonable set of system
+	 * services.
+	 */
+	cninit();
+
+	/*
+	 * Finish the interrupt initialization now that mutexes work and
+	 * enable them.
+	 */
+	intr_init2();
+	wrpr(pil, 0, 0);
+	wrpr(pstate, 0, PSTATE_KERNEL);
+
+	OF_getprop(root, "name", sparc64_model, sizeof(sparc64_model) - 1);
+
+	kdb_init();
+
+#ifdef KDB
+	if (boothowto & RB_KDB)
+		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
+#endif
+}
+
+void
+sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
+{
+	struct trapframe *tf;
+	struct sigframe *sfp;
+	struct sigacts *psp;
+	struct sigframe sf;
+	struct thread *td;
+	struct frame *fp;
+	struct proc *p;
+	u_long sp;
+	int oonstack;
+	int sig;
+
+	oonstack = 0;
+	td = curthread;
+	p = td->td_proc;
+	PROC_LOCK_ASSERT(p, MA_OWNED);
+	sig = ksi->ksi_signo;
+	psp = p->p_sigacts;
+	mtx_assert(&psp->ps_mtx, MA_OWNED);
+	tf = td->td_frame;
+	sp = tf->tf_sp + SPOFF;
+	oonstack = sigonstack(sp);
+
+	CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
+	    catcher, sig);
+
+	/* Make sure we have a signal trampoline to return to. */
+	if (p->p_md.md_sigtramp == NULL) {
+		/*
+		 * No signal trampoline... kill the process.
+		 */
+		CTR0(KTR_SIG, "sendsig: no sigtramp");
+		printf("sendsig: %s is too old, rebuild it\n", p->p_comm);
+		sigexit(td, sig);
+		/* NOTREACHED */
+	}
+
+	/* Save user context. */
+	bzero(&sf, sizeof(sf));
+	get_mcontext(td, &sf.sf_uc.uc_mcontext, 0);
+	sf.sf_uc.uc_sigmask = *mask;
+	sf.sf_uc.uc_stack = td->td_sigstk;
+	sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) ?
+	    ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+
+	/* Allocate and validate space for the signal handler context. */
+	if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
+	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
+		sfp = (struct sigframe *)(td->td_sigstk.ss_sp +
+		    td->td_sigstk.ss_size - sizeof(struct sigframe));
+	} else
+		sfp = (struct sigframe *)sp - 1;
+	mtx_unlock(&psp->ps_mtx);
+	PROC_UNLOCK(p);
+
+	fp = (struct frame *)sfp - 1;
+
+	/* Build the argument list for the signal handler. */
+	tf->tf_out[0] = sig;
+	tf->tf_out[2] = (register_t)&sfp->sf_uc;
+	tf->tf_out[4] = (register_t)catcher;
+	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
+		/* Signal handler installed with SA_SIGINFO. */
+		tf->tf_out[1] = (register_t)&sfp->sf_si;
+
+		/* Fill in POSIX parts. */
+		sf.sf_si = ksi->ksi_info;
+		sf.sf_si.si_signo = sig; /* maybe a translated signal */
+	} else {
+		/* Old FreeBSD-style arguments. */
+		tf->tf_out[1] = ksi->ksi_code;
+		tf->tf_out[3] = (register_t)ksi->ksi_addr;
+	}
+
+	/* Copy the sigframe out to the user's stack. */
+	if (rwindow_save(td) != 0 || copyout(&sf, sfp, sizeof(*sfp)) != 0 ||
+	    suword(&fp->fr_in[6], tf->tf_out[6]) != 0) {
+		/*
+		 * Something is wrong with the stack pointer.
+		 * ...Kill the process.
+		 */
+		CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp);
+		PROC_LOCK(p);
+		sigexit(td, SIGILL);
+		/* NOTREACHED */
+	}
+
+	tf->tf_tpc = (u_long)p->p_md.md_sigtramp;
+	tf->tf_tnpc = tf->tf_tpc + 4;
+	tf->tf_sp = (u_long)fp - SPOFF;
+
+	CTR3(KTR_SIG, "sendsig: return td=%p pc=%#lx sp=%#lx", td, tf->tf_tpc,
+	    tf->tf_sp);
+
+	PROC_LOCK(p);
+	mtx_lock(&psp->ps_mtx);
+}
+
+#ifndef	_SYS_SYSPROTO_H_
+struct sigreturn_args {
+	ucontext_t *ucp;
+};
+#endif
+
+/*
+ * MPSAFE
+ */
+int
+sys_sigreturn(struct thread *td, struct sigreturn_args *uap)
+{
+	struct proc *p;
+	mcontext_t *mc;
+	ucontext_t uc;
+	int error;
+
+	p = td->td_proc;
+	if (rwindow_save(td)) {
+		PROC_LOCK(p);
+		sigexit(td, SIGILL);
+	}
+
+	CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp);
+	if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) {
+		CTR1(KTR_SIG, "sigreturn: efault td=%p", td);
+		return (EFAULT);
+	}
+
+	mc = &uc.uc_mcontext;
+	error = set_mcontext(td, mc);
+	if (error != 0)
+		return (error);
+
+	kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
+
+	CTR4(KTR_SIG, "sigreturn: return td=%p pc=%#lx sp=%#lx tstate=%#lx",
+	    td, mc->_mc_tpc, mc->_mc_sp, mc->_mc_tstate);
+	return (EJUSTRETURN);
+}
+
+/*
+ * Construct a PCB from a trapframe. This is called from kdb_trap() where
+ * we want to start a backtrace from the function that caused us to enter
+ * the debugger. We have the context in the trapframe, but base the trace
+ * on the PCB. The PCB doesn't have to be perfect, as long as it contains
+ * enough for a backtrace.
+ */
+void
+makectx(struct trapframe *tf, struct pcb *pcb)
+{
+
+	pcb->pcb_pc = tf->tf_tpc;
+	pcb->pcb_sp = tf->tf_sp;
+}
+
+int
+get_mcontext(struct thread *td, mcontext_t *mc, int flags)
+{
+	struct trapframe *tf;
+	struct pcb *pcb;
+
+	tf = td->td_frame;
+	pcb = td->td_pcb;
+	/*
+	 * Copy the registers which will be restored by tl0_ret() from the
+	 * trapframe.
+	 * Note that we skip %g7 which is used as the userland TLS register
+	 * and %wstate.
+	 */
+	mc->_mc_flags = _MC_VERSION;
+	mc->mc_global[1] = tf->tf_global[1];
+	mc->mc_global[2] = tf->tf_global[2];
+	mc->mc_global[3] = tf->tf_global[3];
+	mc->mc_global[4] = tf->tf_global[4];
+	mc->mc_global[5] = tf->tf_global[5];
+	mc->mc_global[6] = tf->tf_global[6];
+	if (flags & GET_MC_CLEAR_RET) {
+		mc->mc_out[0] = 0;
+		mc->mc_out[1] = 0;
+	} else {
+		mc->mc_out[0] = tf->tf_out[0];
+		mc->mc_out[1] = tf->tf_out[1];
+	}
+	mc->mc_out[2] = tf->tf_out[2];
+	mc->mc_out[3] = tf->tf_out[3];
+	mc->mc_out[4] = tf->tf_out[4];
+	mc->mc_out[5] = tf->tf_out[5];
+	mc->mc_out[6] = tf->tf_out[6];
+	mc->mc_out[7] = tf->tf_out[7];
+	mc->_mc_fprs = tf->tf_fprs;
+	mc->_mc_fsr = tf->tf_fsr;
+	mc->_mc_gsr = tf->tf_gsr;
+	mc->_mc_tnpc = tf->tf_tnpc;
+	mc->_mc_tpc = tf->tf_tpc;
+	mc->_mc_tstate = tf->tf_tstate;
+	mc->_mc_y = tf->tf_y;
+	critical_enter();
+	if ((tf->tf_fprs & FPRS_FEF) != 0) {
+		savefpctx(pcb->pcb_ufp);
+		tf->tf_fprs &= ~FPRS_FEF;
+		pcb->pcb_flags |= PCB_FEF;
+	}
+	if ((pcb->pcb_flags & PCB_FEF) != 0) {
+		bcopy(pcb->pcb_ufp, mc->mc_fp, sizeof(mc->mc_fp));
+		mc->_mc_fprs |= FPRS_FEF;
+	}
+	critical_exit();
+	return (0);
+}
+
+int
+set_mcontext(struct thread *td, mcontext_t *mc)
+{
+	struct trapframe *tf;
+	struct pcb *pcb;
+
+	if (!TSTATE_SECURE(mc->_mc_tstate) ||
+	    (mc->_mc_flags & ((1L << _MC_VERSION_BITS) - 1)) != _MC_VERSION)
+		return (EINVAL);
+	tf = td->td_frame;
+	pcb = td->td_pcb;
+	/* Make sure the windows are spilled first. */
+	flushw();
+	/*
+	 * Copy the registers which will be restored by tl0_ret() to the
+	 * trapframe.
+	 * Note that we skip %g7 which is used as the userland TLS register
+	 * and %wstate.
+	 */
+	tf->tf_global[1] = mc->mc_global[1];
+	tf->tf_global[2] = mc->mc_global[2];
+	tf->tf_global[3] = mc->mc_global[3];
+	tf->tf_global[4] = mc->mc_global[4];
+	tf->tf_global[5] = mc->mc_global[5];
+	tf->tf_global[6] = mc->mc_global[6];
+	tf->tf_out[0] = mc->mc_out[0];
+	tf->tf_out[1] = mc->mc_out[1];
+	tf->tf_out[2] = mc->mc_out[2];
+	tf->tf_out[3] = mc->mc_out[3];
+	tf->tf_out[4] = mc->mc_out[4];
+	tf->tf_out[5] = mc->mc_out[5];
+	tf->tf_out[6] = mc->mc_out[6];
+	tf->tf_out[7] = mc->mc_out[7];
+	tf->tf_fprs = mc->_mc_fprs;
+	tf->tf_fsr = mc->_mc_fsr;
+	tf->tf_gsr = mc->_mc_gsr;
+	tf->tf_tnpc = mc->_mc_tnpc;
+	tf->tf_tpc = mc->_mc_tpc;
+	tf->tf_tstate = mc->_mc_tstate;
+	tf->tf_y = mc->_mc_y;
+	if ((mc->_mc_fprs & FPRS_FEF) != 0) {
+		tf->tf_fprs = 0;
+		bcopy(mc->mc_fp, pcb->pcb_ufp, sizeof(pcb->pcb_ufp));
+		pcb->pcb_flags |= PCB_FEF;
+	}
+	return (0);
+}
+
+/*
+ * Exit the kernel and execute a firmware call that will not return, as
+ * specified by the arguments.
+ */
+void
+cpu_shutdown(void *args)
+{
+
+#ifdef SMP
+	cpu_mp_shutdown();
+#endif
+	ofw_exit(args);
+}
+
+/*
+ * Flush the D-cache for non-DMA I/O so that the I-cache can
+ * be made coherent later.
+ */
+void
+cpu_flush_dcache(void *ptr, size_t len)
+{
+
+	/* TBD */
+}
+
+/* Get current clock frequency for the given CPU ID. */
+int
+cpu_est_clockrate(int cpu_id, uint64_t *rate)
+{
+	struct pcpu *pc;
+
+	pc = pcpu_find(cpu_id);
+	if (pc == NULL || rate == NULL)
+		return (EINVAL);
+	*rate = pc->pc_clock;
+	return (0);
+}
+
+/*
+ * Duplicate OF_exit() with a different firmware call function that restores
+ * the trap table, otherwise a RED state exception is triggered in at least
+ * some firmware versions.
+ */
+void
+cpu_halt(void)
+{
+	static struct {
+		cell_t name;
+		cell_t nargs;
+		cell_t nreturns;
+	} args = {
+		(cell_t)"exit",
+		0,
+		0
+	};
+
+	cpu_shutdown(&args);
+}
+
+static void
+sparc64_shutdown_final(void *dummy, int howto)
+{
+	static struct {
+		cell_t name;
+		cell_t nargs;
+		cell_t nreturns;
+	} args = {
+		(cell_t)"SUNW,power-off",
+		0,
+		0
+	};
+
+	/* Turn the power off? */
+	if ((howto & RB_POWEROFF) != 0)
+		cpu_shutdown(&args);
+	/* In case of halt, return to the firmware. */
+	if ((howto & RB_HALT) != 0)
+		cpu_halt();
+}
+
+void
+cpu_idle(int busy)
+{
+
+	/* Insert code to halt (until next interrupt) for the idle loop. */
+}
+
+int
+cpu_idle_wakeup(int cpu)
+{
+
+	return (1);
+}
+
+int
+ptrace_set_pc(struct thread *td, u_long addr)
+{
+
+	td->td_frame->tf_tpc = addr;
+	td->td_frame->tf_tnpc = addr + 4;
+	return (0);
+}
+
+int
+ptrace_single_step(struct thread *td)
+{
+
+	/* TODO; */
+	return (0);
+}
+
+int
+ptrace_clear_single_step(struct thread *td)
+{
+
+	/* TODO; */
+	return (0);
+}
+
+void
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
+{
+	struct trapframe *tf;
+	struct pcb *pcb;
+	struct proc *p;
+	u_long sp;
+
+	/* XXX no cpu_exec */
+	p = td->td_proc;
+	p->p_md.md_sigtramp = NULL;
+	if (p->p_md.md_utrap != NULL) {
+		utrap_free(p->p_md.md_utrap);
+		p->p_md.md_utrap = NULL;
+	}
+
+	pcb = td->td_pcb;
+	tf = td->td_frame;
+	sp = rounddown(stack, 16);
+	bzero(pcb, sizeof(*pcb));
+	bzero(tf, sizeof(*tf));
+	tf->tf_out[0] = stack;
+	tf->tf_out[3] = p->p_sysent->sv_psstrings;
+	tf->tf_out[6] = sp - SPOFF - sizeof(struct frame);
+	tf->tf_tnpc = imgp->entry_addr + 4;
+	tf->tf_tpc = imgp->entry_addr;
+	/*
+	 * While we could adhere to the memory model indicated in the ELF
+	 * header, it turns out that just always using TSO performs best.
+	 */
+	tf->tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_MM_TSO;
+
+	td->td_retval[0] = tf->tf_out[0];
+	td->td_retval[1] = tf->tf_out[1];
+}
+
+int
+fill_regs(struct thread *td, struct reg *regs)
+{
+
+	bcopy(td->td_frame, regs, sizeof(*regs));
+	return (0);
+}
+
+int
+set_regs(struct thread *td, struct reg *regs)
+{
+	struct trapframe *tf;
+
+	if (!TSTATE_SECURE(regs->r_tstate))
+		return (EINVAL);
+	tf = td->td_frame;
+	regs->r_wstate = tf->tf_wstate;
+	bcopy(regs, tf, sizeof(*regs));
+	return (0);
+}
+
+int
+fill_dbregs(struct thread *td, struct dbreg *dbregs)
+{
+
+	return (ENOSYS);
+}
+
+int
+set_dbregs(struct thread *td, struct dbreg *dbregs)
+{
+
+	return (ENOSYS);
+}
+
+int
+fill_fpregs(struct thread *td, struct fpreg *fpregs)
+{
+	struct trapframe *tf;
+	struct pcb *pcb;
+
+	pcb = td->td_pcb;
+	tf = td->td_frame;
+	bcopy(pcb->pcb_ufp, fpregs->fr_regs, sizeof(fpregs->fr_regs));
+	fpregs->fr_fsr = tf->tf_fsr;
+	fpregs->fr_gsr = tf->tf_gsr;
+	return (0);
+}
+
+int
+set_fpregs(struct thread *td, struct fpreg *fpregs)
+{
+	struct trapframe *tf;
+	struct pcb *pcb;
+
+	pcb = td->td_pcb;
+	tf = td->td_frame;
+	tf->tf_fprs &= ~FPRS_FEF;
+	bcopy(fpregs->fr_regs, pcb->pcb_ufp, sizeof(pcb->pcb_ufp));
+	tf->tf_fsr = fpregs->fr_fsr;
+	tf->tf_gsr = fpregs->fr_gsr;
+	return (0);
+}
+
+struct md_utrap *
+utrap_alloc(void)
+{
+	struct md_utrap *ut;
+
+	ut = malloc(sizeof(struct md_utrap), M_SUBPROC, M_WAITOK | M_ZERO);
+	ut->ut_refcnt = 1;
+	return (ut);
+}
+
+void
+utrap_free(struct md_utrap *ut)
+{
+	int refcnt;
+
+	if (ut == NULL)
+		return;
+	mtx_pool_lock(mtxpool_sleep, ut);
+	ut->ut_refcnt--;
+	refcnt = ut->ut_refcnt;
+	mtx_pool_unlock(mtxpool_sleep, ut);
+	if (refcnt == 0)
+		free(ut, M_SUBPROC);
+}
+
+struct md_utrap *
+utrap_hold(struct md_utrap *ut)
+{
+
+	if (ut == NULL)
+		return (NULL);
+	mtx_pool_lock(mtxpool_sleep, ut);
+	ut->ut_refcnt++;
+	mtx_pool_unlock(mtxpool_sleep, ut);
+	return (ut);
+}


Property changes on: trunk/sys/sparc64/sparc64/machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/mem.c
===================================================================
--- trunk/sys/sparc64/sparc64/mem.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/mem.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,186 @@
+/* $MidnightBSD$ */
+/*-
+ * 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.
+ * 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
+ *	from: FreeBSD: src/sys/i386/i386/mem.c,v 1.94 2001/09/26
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/mem.c 278746 2015-02-14 08:44:12Z kib $");
+
+/*
+ * Memory special file
+ *
+ * NOTE: other architectures support mmap()'ing the mem and kmem devices; this
+ * might cause illegal aliases to be created for the locked kernel page(s), so
+ * it is not implemented.
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/fcntl.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/memrange.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_page.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+
+#include <machine/cache.h>
+#include <machine/md_var.h>
+#include <machine/pmap.h>
+#include <machine/tlb.h>
+
+#include <machine/memdev.h>
+
+struct mem_range_softc mem_range_softc;
+
+/* ARGSUSED */
+int
+memrw(struct cdev *dev, struct uio *uio, int flags)
+{
+	struct iovec *iov;
+	vm_offset_t eva;
+	vm_offset_t off;
+	vm_offset_t ova;
+	vm_offset_t va;
+	vm_prot_t prot;
+	vm_paddr_t pa;
+	vm_size_t cnt;
+	vm_page_t m;
+	int error;
+	int i;
+	uint32_t colors;
+
+	cnt = 0;
+	colors = 1;
+	error = 0;
+	ova = 0;
+
+	while (uio->uio_resid > 0 && error == 0) {
+		iov = uio->uio_iov;
+		if (iov->iov_len == 0) {
+			uio->uio_iov++;
+			uio->uio_iovcnt--;
+			if (uio->uio_iovcnt < 0)
+				panic("memrw");
+			continue;
+		}
+		if (dev2unit(dev) == CDEV_MINOR_MEM) {
+			pa = uio->uio_offset & ~PAGE_MASK;
+			if (!is_physical_memory(pa)) {
+				error = EFAULT;
+				break;
+			}
+
+			off = uio->uio_offset & PAGE_MASK;
+			cnt = PAGE_SIZE - ((vm_offset_t)iov->iov_base &
+			    PAGE_MASK);
+			cnt = ulmin(cnt, PAGE_SIZE - off);
+			cnt = ulmin(cnt, iov->iov_len);
+
+			m = NULL;
+			for (i = 0; phys_avail[i] != 0; i += 2) {
+				if (pa >= phys_avail[i] &&
+				    pa < phys_avail[i + 1]) {
+					m = PHYS_TO_VM_PAGE(pa);
+					break;
+				}
+			}
+
+			if (m != NULL) {
+				if (ova == 0) {
+					if (dcache_color_ignore == 0)
+						colors = DCACHE_COLORS;
+					ova = kva_alloc(PAGE_SIZE * colors);
+					if (ova == 0) {
+						error = ENOMEM;
+						break;
+					}
+				}
+				if (colors != 1 && m->md.color != -1)
+					va = ova + m->md.color * PAGE_SIZE;
+				else
+					va = ova;
+				pmap_qenter(va, &m, 1);
+				error = uiomove((void *)(va + off), cnt,
+				    uio);
+				pmap_qremove(va, 1);
+			} else {
+				va = TLB_PHYS_TO_DIRECT(pa);
+				error = uiomove((void *)(va + off), cnt,
+				    uio);
+			}
+			break;
+		} else if (dev2unit(dev) == CDEV_MINOR_KMEM) {
+			va = trunc_page(uio->uio_offset);
+			eva = round_page(uio->uio_offset + iov->iov_len);
+
+			/*
+			 * Make sure that all of the pages are currently
+			 * resident so we don't create any zero fill pages.
+			 */
+			for (; va < eva; va += PAGE_SIZE)
+				if (pmap_kextract(va) == 0)
+					return (EFAULT);
+
+			prot = (uio->uio_rw == UIO_READ) ? VM_PROT_READ :
+			    VM_PROT_WRITE;
+			va = uio->uio_offset;
+			if (va < VM_MIN_DIRECT_ADDRESS &&
+			    kernacc((void *)va, iov->iov_len, prot) == FALSE)
+				return (EFAULT);
+
+			error = uiomove((void *)va, iov->iov_len, uio);
+			break;
+		}
+		/* else panic! */
+	}
+	if (ova != 0)
+		kva_free(ova, PAGE_SIZE * colors);
+	return (error);
+}


Property changes on: trunk/sys/sparc64/sparc64/mem.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/mp_exception.S
===================================================================
--- trunk/sys/sparc64/sparc64/mp_exception.S	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/mp_exception.S	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,310 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 Jake Burkholder.
+ * 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.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/mp_exception.S 293853 2016-01-13 21:38:52Z marius $");
+
+#include <machine/asi.h>
+#include <machine/asmacros.h>
+#include <machine/cache.h>
+#include <machine/ktr.h>
+#include <machine/pstate.h>
+
+#include "assym.s"
+
+	.register	%g2, #ignore
+	.register	%g3, #ignore
+
+#define	IPI_DONE(r1, r2, r3, r4, r5)					\
+	lduw	[PCPU(CPUID)], r2 ;					\
+	mov	_NCPUBITS, r3 ;						\
+	udivx	r2, r3, r4 ;						\
+	srl	r4, 0, r5 ;						\
+	sllx	r5, PTR_SHIFT, r5 ;					\
+	add	r1, r5, r1 ;						\
+	smul	r4, r3, r3 ;						\
+	sub	r2, r3, r3 ;						\
+	mov	1, r4 ;							\
+	sllx	r4, r3, r4 ;						\
+	ATOMIC_CLEAR_LONG(r1, r2, r3, r4)
+
+/*
+ * Invalidate a physical page in the data cache.  For UltraSPARC I and II.
+ */
+ENTRY(tl_ipi_spitfire_dcache_page_inval)
+#if KTR_COMPILE & KTR_SMP
+	CATR(KTR_SMP, "tl_ipi_spitfire_dcache_page_inval: pa=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	ldx	[%g5 + ICA_PA], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+9:
+#endif
+
+	ldx	[%g5 + ICA_PA], %g6
+	srlx	%g6, PAGE_SHIFT - DC_TAG_SHIFT, %g6
+
+	lduw	[PCPU(CACHE) + DC_SIZE], %g3
+	lduw	[PCPU(CACHE) + DC_LINESIZE], %g4
+	sub	%g3, %g4, %g2
+
+1:	ldxa	[%g2] ASI_DCACHE_TAG, %g1
+	srlx	%g1, DC_VALID_SHIFT, %g3
+	andcc	%g3, DC_VALID_MASK, %g0
+	bz,pt	%xcc, 2f
+	 set	DC_TAG_MASK, %g3
+	sllx	%g3, DC_TAG_SHIFT, %g3
+	and	%g1, %g3, %g1
+	cmp	%g1, %g6
+	bne,a,pt %xcc, 2f
+	 nop
+	stxa	%g1, [%g2] ASI_DCACHE_TAG
+	membar	#Sync
+
+2:	brgz,pt	%g2, 1b
+	 sub	%g2, %g4, %g2
+
+	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
+	retry
+END(tl_ipi_spitfire_dcache_page_inval)
+
+/*
+ * Invalidate a physical page in the instruction cache.  For UltraSPARC I and
+ * II.
+ */
+ENTRY(tl_ipi_spitfire_icache_page_inval)
+#if KTR_COMPILE & KTR_SMP
+	CATR(KTR_SMP, "tl_ipi_spitfire_icache_page_inval: pa=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	ldx	[%g5 + ICA_PA], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+9:
+#endif
+
+	ldx	[%g5 + ICA_PA], %g6
+	srlx	%g6, PAGE_SHIFT - IC_TAG_SHIFT, %g6
+
+	lduw	[PCPU(CACHE) + IC_SIZE], %g3
+	lduw	[PCPU(CACHE) + IC_LINESIZE], %g4
+	sub	%g3, %g4, %g2
+
+1:	ldda	[%g2] ASI_ICACHE_TAG, %g0 /*, %g1 */
+	srlx	%g1, IC_VALID_SHIFT, %g3
+	andcc	%g3, IC_VALID_MASK, %g0
+	bz,pt	%xcc, 2f
+	 set	IC_TAG_MASK, %g3
+	sllx	%g3, IC_TAG_SHIFT, %g3
+	and	%g1, %g3, %g1
+	cmp	%g1, %g6
+	bne,a,pt %xcc, 2f
+	 nop
+	stxa	%g1, [%g2] ASI_ICACHE_TAG
+	membar	#Sync
+
+2:	brgz,pt	%g2, 1b
+	 sub	%g2, %g4, %g2
+
+	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
+	retry
+END(tl_ipi_spitfire_icache_page_inval)
+
+/*
+ * Invalidate a physical page in the data cache.  For UltraSPARC III.
+ */
+ENTRY(tl_ipi_cheetah_dcache_page_inval)
+#if KTR_COMPILE & KTR_SMP
+	CATR(KTR_SMP, "tl_ipi_cheetah_dcache_page_inval: pa=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	ldx	[%g5 + ICA_PA], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+9:
+#endif
+
+	ldx	[%g5 + ICA_PA], %g1
+
+	set	PAGE_SIZE, %g2
+	add	%g1, %g2, %g3
+
+	lduw	[PCPU(CACHE) + DC_LINESIZE], %g2
+
+1:	stxa	%g0, [%g1] ASI_DCACHE_INVALIDATE
+	membar	#Sync
+
+	add	%g1, %g2, %g1
+	cmp	%g1, %g3
+	blt,a,pt %xcc, 1b
+	 nop
+
+	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
+	retry
+END(tl_ipi_cheetah_dcache_page_inval)
+
+/*
+ * Trigger a softint at the desired level.
+ */
+ENTRY(tl_ipi_level)
+#if KTR_COMPILE & KTR_SMP
+	CATR(KTR_SMP, "tl_ipi_level: cpuid=%d mid=%d d1=%#lx d2=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	lduw	[PCPU(CPUID)], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	lduw	[PCPU(MID)], %g2
+	stx	%g2, [%g1 + KTR_PARM2]
+	stx	%g4, [%g1 + KTR_PARM3]
+	stx	%g5, [%g1 + KTR_PARM4]
+9:
+#endif
+
+	mov	1, %g1
+	sllx	%g1, %g5, %g1
+	wr	%g1, 0, %set_softint
+	retry
+END(tl_ipi_level)
+
+/*
+ * Demap a page from the dtlb and/or itlb.
+ */
+ENTRY(tl_ipi_tlb_page_demap)
+#if KTR_COMPILE & KTR_SMP
+	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	ldx	[%g5 + ITA_PMAP], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	ldx	[%g5 + ITA_VA], %g2
+	stx	%g2, [%g1 + KTR_PARM2]
+9:
+#endif
+
+	ldx	[%g5 + ITA_PMAP], %g1
+
+	SET(kernel_pmap_store, %g3, %g2)
+	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
+
+	cmp	%g1, %g2
+	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
+
+	ldx	[%g5 + ITA_VA], %g2
+	or	%g2, %g3, %g2
+
+	sethi	%hi(KERNBASE), %g3
+	stxa	%g0, [%g2] ASI_DMMU_DEMAP
+	stxa	%g0, [%g2] ASI_IMMU_DEMAP
+	flush	%g3
+
+	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
+	retry
+END(tl_ipi_tlb_page_demap)
+
+/*
+ * Demap a range of pages from the dtlb and itlb.
+ */
+ENTRY(tl_ipi_tlb_range_demap)
+#if KTR_COMPILE & KTR_SMP
+	CATR(KTR_SMP, "ipi_tlb_range_demap: pm=%p start=%#lx end=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	ldx	[%g5 + ITA_PMAP], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	ldx	[%g5 + ITA_START], %g2
+	stx	%g2, [%g1 + KTR_PARM2]
+	ldx	[%g5 + ITA_END], %g2
+	stx	%g2, [%g1 + KTR_PARM3]
+9:
+#endif
+
+	ldx	[%g5 + ITA_PMAP], %g1
+
+	SET(kernel_pmap_store, %g3, %g2)
+	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
+
+	cmp	%g1, %g2
+	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
+
+	ldx	[%g5 + ITA_START], %g1
+	ldx	[%g5 + ITA_END], %g2
+
+	sethi	%hi(KERNBASE), %g6
+1:	or	%g1, %g3, %g4
+	stxa	%g0, [%g4] ASI_DMMU_DEMAP
+	stxa	%g0, [%g4] ASI_IMMU_DEMAP
+	flush	%g6
+
+	set	PAGE_SIZE, %g6
+	add	%g1, %g6, %g1
+	cmp	%g1, %g2
+	blt,a,pt %xcc, 1b
+	 sethi	%hi(KERNBASE), %g6
+
+	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
+	retry
+END(tl_ipi_tlb_range_demap)
+
+/*
+ * Demap the primary context from the dtlb and itlb.
+ */
+ENTRY(tl_ipi_tlb_context_demap)
+#if KTR_COMPILE & KTR_SMP
+	CATR(KTR_SMP, "tl_ipi_tlb_context_demap: pm=%p va=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	ldx	[%g5 + ITA_PMAP], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	ldx	[%g5 + ITA_VA], %g2
+	stx	%g2, [%g1 + KTR_PARM2]
+9:
+#endif
+
+	mov	TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, %g1
+	sethi	%hi(KERNBASE), %g3
+	stxa	%g0, [%g1] ASI_DMMU_DEMAP
+	stxa	%g0, [%g1] ASI_IMMU_DEMAP
+	flush	%g3
+
+	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
+	retry
+END(tl_ipi_tlb_context_demap)
+
+/*
+ * Read %stick.
+ */
+ENTRY(tl_ipi_stick_rd)
+	ldx	[%g5 + IRA_VAL], %g1
+	rd	%asr24, %g2
+	stx	%g2, [%g1]
+
+	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
+	retry
+END(tl_ipi_stick_rd)
+
+/*
+ * Read %tick.
+ */
+ENTRY(tl_ipi_tick_rd)
+	ldx	[%g5 + IRA_VAL], %g1
+	rd	%tick, %g2
+	stx	%g2, [%g1]
+
+	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
+	retry
+END(tl_ipi_tick_rd)


Property changes on: trunk/sys/sparc64/sparc64/mp_exception.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/mp_locore.S
===================================================================
--- trunk/sys/sparc64/sparc64/mp_locore.S	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/mp_locore.S	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,297 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 Jake Burkholder.
+ * Copyright (c) 2008 Marius Strobl <marius at 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, 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.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/mp_locore.S 222828 2011-06-07 17:33:39Z marius $");
+
+#include <machine/asi.h>
+#include <machine/asmacros.h>
+#include <machine/intr_machdep.h>
+#include <machine/ktr.h>
+#include <machine/pstate.h>
+#include <machine/smp.h>
+#include <machine/ver.h>
+
+#include "assym.s"
+
+	.register	%g2, #ignore
+	.register	%g3, #ignore
+
+	.text
+	_ALIGN_TEXT
+	/*
+	 * Initialize misc. state to known values: interrupts disabled, normal
+	 * globals, windows flushed (cr = 0, cs = nwindows - 1), PIL_TICK and
+	 * floating point disabled.
+	 * Note that some firmware versions don't implement a clean window
+	 * trap handler so we unfortunately can't clear the windows by setting
+	 * %cleanwin to zero here.
+	 */
+1:	wrpr	%g0, PSTATE_NORMAL, %pstate
+	wrpr	%g0, PIL_TICK, %pil
+	wr	%g0, 0, %fprs
+
+	rdpr	%ver, %l7
+	srlx	%l7, VER_IMPL_SHIFT, %l7
+	sll	%l7, VER_IMPL_SIZE, %l7
+	srl	%l7, VER_IMPL_SIZE, %l7
+	cmp	%l7, CPU_IMPL_ULTRASPARCIIIp
+	bne	%icc, 3f
+	 nop
+
+	/*
+	 * Relocate the locked entry in it16 slot 0 (if existent)
+	 * as part of working around Cheetah+ erratum 34.
+	 */
+
+	setx	TD_V | TD_L, %l1, %l0
+	/*
+	 * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work
+	 * around errata of USIII and beyond.
+	 */
+	ldxa	[%g0] ASI_ITLB_DATA_ACCESS_REG, %g0
+	ldxa	[%g0] ASI_ITLB_DATA_ACCESS_REG, %l6
+	and	%l6, %l0, %l1
+	cmp	%l0, %l1
+	bne	%xcc, 3f
+	 nop
+
+	/* Flush the mapping of slot 0. */
+	ldxa	[%g0] ASI_ITLB_TAG_READ_REG, %l5
+	srlx	%l5, TAR_VPN_SHIFT, %l0
+	sllx	%l0, TAR_VPN_SHIFT, %l0
+	or	%l0, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %l0
+	stxa	%g0, [%l0] ASI_IMMU_DEMAP
+	/* The USIII-family ignores the address. */
+	flush	%g0
+
+	/*
+	 * Search a replacement slot != 0 and enter the data and tag
+	 * that formerly were in slot 0.
+	 */
+	mov	(1 << TLB_DAR_SLOT_SHIFT), %l4
+	setx	TD_V, %l1, %l0
+	/*
+	 * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work
+	 * around errata of USIII and beyond.
+	 */
+2:	ldxa	[%l4] ASI_ITLB_DATA_ACCESS_REG, %g0
+	ldxa	[%l4] ASI_ITLB_DATA_ACCESS_REG, %l1
+	and	%l1, %l0, %l1
+	cmp	%l0, %l1
+	be,a	%xcc, 2b
+	 add	%l4, (1 << TLB_DAR_SLOT_SHIFT), %l4
+	wr	%g0, ASI_IMMU, %asi
+	stxa	%l5, [%g0 + AA_IMMU_TAR] %asi
+	stxa	%l6, [%l4] ASI_ITLB_DATA_ACCESS_REG
+	/* The USIII-family ignores the address. */
+	flush	%g0
+
+3:	rd	%pc, %l6
+	ldx	[%l6 + (9f-3b)], %l1
+	add	%l6, (11f-3b), %l2
+	clr	%l3
+4:	cmp	%l3, %l1
+	be	%xcc, 8f
+	 nop
+	ldx	[%l2 + TTE_VPN], %l4
+	ldx	[%l2 + TTE_DATA], %l5
+	srlx	%l4, TV_SIZE_BITS, %l4
+	sllx	%l4, PAGE_SHIFT_4M, %l4
+	wr	%g0, ASI_DMMU, %asi
+	stxa	%l4, [%g0 + AA_DMMU_TAR] %asi
+	stxa	%l5, [%g0] ASI_DTLB_DATA_IN_REG
+	membar	#Sync
+
+	cmp	%l7, CPU_IMPL_ULTRASPARCIIIp
+	bne	%icc, 6f
+	 wr	%g0, ASI_IMMU, %asi
+
+	/*
+	 * Search an unused slot != 0 and explicitly enter the data
+	 * and tag there in order to avoid Cheetah+ erratum 34.
+	 */
+	mov	(1 << TLB_DAR_SLOT_SHIFT), %l0
+	setx	TD_V, %o1, %o0
+	/*
+	 * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work
+	 * around errata of USIII and beyond.
+	 */
+5:	ldxa	[%l0] ASI_ITLB_DATA_ACCESS_REG, %g0
+	ldxa	[%l0] ASI_ITLB_DATA_ACCESS_REG, %o1
+	and	%o1, %o0, %o1
+	cmp	%o0, %o1
+	be,a	%xcc, 5b
+	 add	%l0, (1 << TLB_DAR_SLOT_SHIFT), %l0
+	sethi	%hi(KERNBASE), %o0
+	stxa	%l4, [%g0 + AA_IMMU_TAR] %asi
+	stxa	%l5, [%l0] ASI_ITLB_DATA_ACCESS_REG
+	flush	%o0
+	ba	%xcc, 7f
+	 nop
+
+6:	sethi	%hi(KERNBASE), %l0
+	stxa	%l4, [%g0 + AA_IMMU_TAR] %asi
+	stxa	%l5, [%g0] ASI_ITLB_DATA_IN_REG
+	flush	%l0
+7:	add	%l2, 1 << TTE_SHIFT, %l2
+	add	%l3, 1, %l3
+	ba	%xcc, 4b
+	 nop
+8:	ldx	[%l6 + (10f-3b)], %l1
+	jmpl	%l1, %g0
+	 nop
+	_ALIGN_DATA
+9:	.xword	0x0
+10:	.xword	0x0
+11:
+
+DATA(mp_tramp_code)
+	.xword	1b
+DATA(mp_tramp_code_len)
+	.xword	11b-1b
+DATA(mp_tramp_tlb_slots)
+	.xword	9b-1b
+DATA(mp_tramp_func)
+	.xword	10b-1b
+
+/*
+ * void mp_startup(void)
+ */
+ENTRY(mp_startup)
+	SET(cpu_start_args, %l1, %l0)
+
+	mov	CPU_TICKSYNC, %l1
+	membar	#StoreLoad
+	stw	%l1, [%l0 + CSA_STATE]
+
+1:	ldx	[%l0 + CSA_TICK], %l1
+	brz	%l1, 1b
+	 nop
+	wrpr	%l1, 0, %tick
+
+	rdpr	%ver, %l1
+	stx	%l1, [%l0 + CSA_VER]
+
+	srlx	%l1, VER_IMPL_SHIFT, %l1
+	sll	%l1, VER_IMPL_SIZE, %l1
+	srl	%l1, VER_IMPL_SIZE, %l1
+	cmp	%l1, CPU_IMPL_SPARC64V
+	bl	%icc, 4f
+	 nop
+	cmp	%l1, CPU_IMPL_ULTRASPARCI
+	bl	%icc, 2f
+	 nop
+	cmp	%l1, CPU_IMPL_ULTRASPARCIII
+	bl	%icc, 4f
+	 nop
+2:	mov	CPU_STICKSYNC, %l2
+	membar	#StoreLoad
+	stw	%l2, [%l0 + CSA_STATE]
+
+3:	ldx	[%l0 + CSA_STICK], %l2
+	brz	%l2, 3b
+	 nop
+	wr	%l2, 0, %asr24
+
+4:	call	cpu_get_mid
+	 mov	%l1, %o0
+
+	/*
+	 * Inform the boot processor we have inited.
+	 */
+	mov	CPU_INIT, %l1
+	membar	#LoadStore
+	stw	%l1, [%l0 + CSA_STATE]
+
+	/*
+	 * Wait till its our turn to bootstrap.
+	 */
+5:	lduw	[%l0 + CSA_MID], %l1
+	cmp	%l1, %o0
+	bne	%xcc, 5b
+	 nop
+
+	add	%l0, CSA_TTES, %l1
+	clr	%l2
+
+	/*
+	 * Map the per-CPU pages.
+	 */
+6:	sllx	%l2, TTE_SHIFT, %l3
+	add	%l1, %l3, %l3
+
+	ldx	[%l3 + TTE_VPN], %l4
+	ldx	[%l3 + TTE_DATA], %l5
+
+	wr	%g0, ASI_DMMU, %asi
+	srlx	%l4, TV_SIZE_BITS, %l4
+	sllx	%l4, PAGE_SHIFT_8K, %l4
+	stxa	%l4, [%g0 + AA_DMMU_TAR] %asi
+	stxa	%l5, [%g0] ASI_DTLB_DATA_IN_REG
+	membar	#Sync
+
+	add	%l2, 1, %l2
+	cmp	%l2, PCPU_PAGES
+	bne	%xcc, 6b
+	 nop
+
+	/*
+	 * Get onto our per-CPU panic stack, which precedes the struct pcpu
+	 * in the per-CPU page.
+	 */
+	ldx	[%l0 + CSA_PCPU], %l1
+	set	PCPU_PAGES * PAGE_SIZE - PC_SIZEOF, %l2
+	add	%l1, %l2, %l1
+	sub	%l1, SPOFF + CCFSZ, %sp
+
+	/* Initialize global registers. */
+	call	cpu_setregs
+	 mov	%l1, %o0
+
+#if KTR_COMPILE & KTR_SMP
+	CATR(KTR_SMP,
+	    "mp_startup: bootstrap cpuid=%d mid=%d pcpu=%#lx data=%#lx sp=%#lx"
+	    , %g1, %g2, %g3, 7, 8, 9)
+	lduw	[PCPU(CPUID)], %g2
+	stx	%g2, [%g1 + KTR_PARM1]
+	lduw	[PCPU(MID)], %g2
+	stx	%g2, [%g1 + KTR_PARM2]
+	stx	%l1, [%g1 + KTR_PARM3]
+	stx	%sp, [%g1 + KTR_PARM5]
+9:
+#endif
+
+	/*
+	 * And away we go.  This doesn't return.
+	 */
+	call	cpu_mp_bootstrap
+	 mov	%l1, %o0
+	sir
+	! NOTREACHED
+END(mp_startup)


Property changes on: trunk/sys/sparc64/sparc64/mp_locore.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/mp_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/mp_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/mp_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,811 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1997 Berkeley Software Design, Inc. 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. Berkeley Software Design Inc's name may not be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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 BSDI: locore.s,v 1.36.2.15 1999/08/23 22:34:41 cp Exp
+ */
+/*-
+ * Copyright (c) 2002 Jake Burkholder.
+ * Copyright (c) 2007 - 2010 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/mp_machdep.c 292771 2015-12-27 14:39:47Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
+#include <sys/smp.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_map.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <machine/asi.h>
+#include <machine/atomic.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/md_var.h>
+#include <machine/metadata.h>
+#include <machine/ofw_machdep.h>
+#include <machine/pcb.h>
+#include <machine/smp.h>
+#include <machine/tick.h>
+#include <machine/tlb.h>
+#include <machine/tsb.h>
+#include <machine/tte.h>
+#include <machine/ver.h>
+
+#define	SUNW_STARTCPU		"SUNW,start-cpu"
+#define	SUNW_STOPSELF		"SUNW,stop-self"
+
+static ih_func_t cpu_ipi_ast;
+static ih_func_t cpu_ipi_hardclock;
+static ih_func_t cpu_ipi_preempt;
+static ih_func_t cpu_ipi_stop;
+
+/*
+ * Argument area used to pass data to non-boot processors as they start up.
+ * This must be statically initialized with a known invalid CPU module ID,
+ * since the other processors will use it before the boot CPU enters the
+ * kernel.
+ */
+struct	cpu_start_args cpu_start_args = { 0, -1, -1, 0, 0, 0 };
+struct	ipi_cache_args ipi_cache_args;
+struct	ipi_rd_args ipi_rd_args;
+struct	ipi_tlb_args ipi_tlb_args;
+struct	pcb stoppcbs[MAXCPU];
+
+struct	mtx ipi_mtx;
+
+cpu_ipi_selected_t *cpu_ipi_selected;
+cpu_ipi_single_t *cpu_ipi_single;
+
+static u_int cpuid_to_mid[MAXCPU];
+static u_int cpuids = 1;
+static volatile cpuset_t shutdown_cpus;
+static char ipi_pbuf[CPUSETBUFSIZ];
+static vm_offset_t mp_tramp;
+
+static void ap_count(phandle_t node, u_int mid, u_int cpu_impl);
+static void ap_start(phandle_t node, u_int mid, u_int cpu_impl);
+static void cpu_mp_unleash(void *v);
+static void foreach_ap(phandle_t node, void (*func)(phandle_t node,
+    u_int mid, u_int cpu_impl));
+static void sun4u_startcpu(phandle_t cpu, void *func, u_long arg);
+
+static cpu_ipi_selected_t cheetah_ipi_selected;
+static cpu_ipi_single_t cheetah_ipi_single;
+static cpu_ipi_selected_t jalapeno_ipi_selected;
+static cpu_ipi_single_t jalapeno_ipi_single;
+static cpu_ipi_selected_t spitfire_ipi_selected;
+static cpu_ipi_single_t spitfire_ipi_single;
+
+SYSINIT(cpu_mp_unleash, SI_SUB_SMP, SI_ORDER_FIRST, cpu_mp_unleash, NULL);
+
+void
+mp_init(void)
+{
+	struct tte *tp;
+	int i;
+
+	mp_tramp = (vm_offset_t)OF_claim(NULL, PAGE_SIZE, PAGE_SIZE);
+	if (mp_tramp == (vm_offset_t)-1)
+		panic("%s", __func__);
+	bcopy(mp_tramp_code, (void *)mp_tramp, mp_tramp_code_len);
+	*(vm_offset_t *)(mp_tramp + mp_tramp_tlb_slots) = kernel_tlb_slots;
+	*(vm_offset_t *)(mp_tramp + mp_tramp_func) = (vm_offset_t)mp_startup;
+	tp = (struct tte *)(mp_tramp + mp_tramp_code_len);
+	for (i = 0; i < kernel_tlb_slots; i++) {
+		tp[i].tte_vpn = TV_VPN(kernel_tlbs[i].te_va, TS_4M);
+		tp[i].tte_data = TD_V | TD_4M | TD_PA(kernel_tlbs[i].te_pa) |
+		    TD_L | TD_CP | TD_CV | TD_P | TD_W;
+	}
+	for (i = 0; i < PAGE_SIZE; i += sizeof(vm_offset_t))
+		flush(mp_tramp + i);
+}
+
+static void
+foreach_ap(phandle_t node, void (*func)(phandle_t node, u_int mid,
+    u_int cpu_impl))
+{
+	static char type[sizeof("cpu")];
+	phandle_t child;
+	uint32_t cpu_impl, portid;
+
+	/* There's no need to traverse the whole OFW tree twice. */
+	if (mp_maxid > 0 && cpuids > mp_maxid)
+		return;
+
+	for (; node != 0; node = OF_peer(node)) {
+		child = OF_child(node);
+		if (child > 0)
+			foreach_ap(child, func);
+		else {
+			if (OF_getprop(node, "device_type", type,
+			    sizeof(type)) <= 0)
+				continue;
+			if (strcmp(type, "cpu") != 0)
+				continue;
+			if (OF_getprop(node, "implementation#", &cpu_impl,
+			    sizeof(cpu_impl)) <= 0)
+				panic("%s: couldn't determine CPU "
+				    "implementation", __func__);
+			if (OF_getprop(node, cpu_portid_prop(cpu_impl),
+			    &portid, sizeof(portid)) <= 0)
+				panic("%s: couldn't determine CPU port ID",
+				    __func__);
+			if (portid == PCPU_GET(mid))
+				continue;
+			(*func)(node, portid, cpu_impl);
+		}
+	}
+}
+
+/*
+ * Probe for other CPUs.
+ */
+void
+cpu_mp_setmaxid(void)
+{
+
+	CPU_SETOF(curcpu, &all_cpus);
+	mp_ncpus = 1;
+
+	foreach_ap(OF_child(OF_peer(0)), ap_count);
+	mp_ncpus = MIN(mp_ncpus, MAXCPU);
+	mp_maxid = mp_ncpus - 1;
+}
+
+static void
+ap_count(phandle_t node __unused, u_int mid __unused, u_int cpu_impl __unused)
+{
+
+	mp_ncpus++;
+}
+
+int
+cpu_mp_probe(void)
+{
+
+	return (mp_maxid > 0);
+}
+
+struct cpu_group *
+cpu_topo(void)
+{
+
+	return (smp_topo_none());
+}
+
+static void
+sun4u_startcpu(phandle_t cpu, void *func, u_long arg)
+{
+	static struct {
+		cell_t	name;
+		cell_t	nargs;
+		cell_t	nreturns;
+		cell_t	cpu;
+		cell_t	func;
+		cell_t	arg;
+	} args = {
+		(cell_t)SUNW_STARTCPU,
+		3,
+	};
+
+	args.cpu = cpu;
+	args.func = (cell_t)func;
+	args.arg = (cell_t)arg;
+	ofw_entry(&args);
+}
+
+/*
+ * Fire up any non-boot processors.
+ */
+void
+cpu_mp_start(void)
+{
+	u_int cpu_impl, isjbus;
+
+	mtx_init(&ipi_mtx, "ipi", NULL, MTX_SPIN);
+
+	isjbus = 0;
+	cpu_impl = PCPU_GET(impl);
+	if (cpu_impl == CPU_IMPL_ULTRASPARCIIIi ||
+	    cpu_impl == CPU_IMPL_ULTRASPARCIIIip) {
+		isjbus = 1;
+		cpu_ipi_selected = jalapeno_ipi_selected;
+		cpu_ipi_single = jalapeno_ipi_single;
+	} else if (cpu_impl == CPU_IMPL_SPARC64V ||
+	    cpu_impl >= CPU_IMPL_ULTRASPARCIII) {
+		cpu_ipi_selected = cheetah_ipi_selected;
+		cpu_ipi_single = cheetah_ipi_single;
+	} else {
+		cpu_ipi_selected = spitfire_ipi_selected;
+		cpu_ipi_single = spitfire_ipi_single;
+	}
+
+	intr_setup(PIL_AST, cpu_ipi_ast, -1, NULL, NULL);
+	intr_setup(PIL_RENDEZVOUS, (ih_func_t *)smp_rendezvous_action,
+	    -1, NULL, NULL);
+	intr_setup(PIL_STOP, cpu_ipi_stop, -1, NULL, NULL);
+	intr_setup(PIL_PREEMPT, cpu_ipi_preempt, -1, NULL, NULL);
+	intr_setup(PIL_HARDCLOCK, cpu_ipi_hardclock, -1, NULL, NULL);
+
+	cpuid_to_mid[curcpu] = PCPU_GET(mid);
+
+	foreach_ap(OF_child(OF_peer(0)), ap_start);
+	KASSERT(!isjbus || mp_ncpus <= IDR_JALAPENO_MAX_BN_PAIRS,
+	    ("%s: can only IPI a maximum of %d JBus-CPUs",
+	    __func__, IDR_JALAPENO_MAX_BN_PAIRS));
+}
+
+static void
+ap_start(phandle_t node, u_int mid, u_int cpu_impl)
+{
+	volatile struct cpu_start_args *csa;
+	struct pcpu *pc;
+	register_t s;
+	vm_offset_t va;
+	u_int cpuid;
+	uint32_t clock;
+
+	if (cpuids > mp_maxid)
+		return;
+
+	if (OF_getprop(node, "clock-frequency", &clock, sizeof(clock)) <= 0)
+		panic("%s: couldn't determine CPU frequency", __func__);
+	if (clock != PCPU_GET(clock))
+		tick_et_use_stick = 1;
+
+	csa = &cpu_start_args;
+	csa->csa_state = 0;
+	sun4u_startcpu(node, (void *)mp_tramp, 0);
+	s = intr_disable();
+	while (csa->csa_state != CPU_TICKSYNC)
+		;
+	membar(StoreLoad);
+	csa->csa_tick = rd(tick);
+	if (cpu_impl == CPU_IMPL_SPARC64V ||
+	    cpu_impl >= CPU_IMPL_ULTRASPARCIII) {
+		while (csa->csa_state != CPU_STICKSYNC)
+			;
+		membar(StoreLoad);
+		csa->csa_stick = rdstick();
+	}
+	while (csa->csa_state != CPU_INIT)
+		;
+	csa->csa_tick = csa->csa_stick = 0;
+	intr_restore(s);
+
+	cpuid = cpuids++;
+	cpuid_to_mid[cpuid] = mid;
+	cpu_identify(csa->csa_ver, clock, cpuid);
+
+	va = kmem_malloc(kernel_arena, PCPU_PAGES * PAGE_SIZE,
+	    M_WAITOK | M_ZERO);
+	pc = (struct pcpu *)(va + (PCPU_PAGES * PAGE_SIZE)) - 1;
+	pcpu_init(pc, cpuid, sizeof(*pc));
+	dpcpu_init((void *)kmem_malloc(kernel_arena, DPCPU_SIZE,
+	    M_WAITOK | M_ZERO), cpuid);
+	pc->pc_addr = va;
+	pc->pc_clock = clock;
+	pc->pc_impl = cpu_impl;
+	pc->pc_mid = mid;
+	pc->pc_node = node;
+
+	cache_init(pc);
+
+	CPU_SET(cpuid, &all_cpus);
+	intr_add_cpu(cpuid);
+}
+
+void
+cpu_mp_announce(void)
+{
+
+}
+
+static void
+cpu_mp_unleash(void *v __unused)
+{
+	volatile struct cpu_start_args *csa;
+	struct pcpu *pc;
+	register_t s;
+	vm_offset_t va;
+	vm_paddr_t pa;
+	u_int ctx_inc;
+	u_int ctx_min;
+	int i;
+
+	ctx_min = TLB_CTX_USER_MIN;
+	ctx_inc = (TLB_CTX_USER_MAX - 1) / mp_ncpus;
+	csa = &cpu_start_args;
+	csa->csa_count = mp_ncpus;
+	STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) {
+		pc->pc_tlb_ctx = ctx_min;
+		pc->pc_tlb_ctx_min = ctx_min;
+		pc->pc_tlb_ctx_max = ctx_min + ctx_inc;
+		ctx_min += ctx_inc;
+
+		if (pc->pc_cpuid == curcpu)
+			continue;
+		KASSERT(pc->pc_idlethread != NULL,
+		    ("%s: idlethread", __func__));
+		pc->pc_curthread = pc->pc_idlethread;
+		pc->pc_curpcb = pc->pc_curthread->td_pcb;
+		for (i = 0; i < PCPU_PAGES; i++) {
+			va = pc->pc_addr + i * PAGE_SIZE;
+			pa = pmap_kextract(va);
+			if (pa == 0)
+				panic("%s: pmap_kextract", __func__);
+			csa->csa_ttes[i].tte_vpn = TV_VPN(va, TS_8K);
+			csa->csa_ttes[i].tte_data = TD_V | TD_8K | TD_PA(pa) |
+			    TD_L | TD_CP | TD_CV | TD_P | TD_W;
+		}
+		csa->csa_state = 0;
+		csa->csa_pcpu = pc->pc_addr;
+		csa->csa_mid = pc->pc_mid;
+		s = intr_disable();
+		while (csa->csa_state != CPU_BOOTSTRAP)
+			;
+		intr_restore(s);
+	}
+
+	membar(StoreLoad);
+	csa->csa_count = 0;
+}
+
+void
+cpu_mp_bootstrap(struct pcpu *pc)
+{
+	volatile struct cpu_start_args *csa;
+
+	csa = &cpu_start_args;
+
+	/* Do CPU-specific initialization. */
+	if (pc->pc_impl >= CPU_IMPL_ULTRASPARCIII)
+		cheetah_init(pc->pc_impl);
+	else if (pc->pc_impl == CPU_IMPL_SPARC64V)
+		zeus_init(pc->pc_impl);
+
+	/*
+	 * Enable the caches.  Note that his may include applying workarounds.
+	 */
+	cache_enable(pc->pc_impl);
+
+	/*
+	 * Clear (S)TICK timer(s) (including NPT) and ensure they are stopped.
+	 */
+	tick_clear(pc->pc_impl);
+	tick_stop(pc->pc_impl);
+
+	/* Set the kernel context. */
+	pmap_set_kctx();
+
+	/* Lock the kernel TSB in the TLB if necessary. */
+	if (tsb_kernel_ldd_phys == 0)
+		pmap_map_tsb();
+
+	/*
+	 * Flush all non-locked TLB entries possibly left over by the
+	 * firmware.
+	 */
+	tlb_flush_nonlocked();
+
+	/*
+	 * Enable interrupts.
+	 * Note that the PIL we be lowered indirectly via sched_throw(NULL)
+	 * when fake spinlock held by the idle thread eventually is released.
+	 */
+	wrpr(pstate, 0, PSTATE_KERNEL);
+
+	smp_cpus++;
+	KASSERT(curthread != NULL, ("%s: curthread", __func__));
+	printf("SMP: AP CPU #%d Launched!\n", curcpu);
+
+	csa->csa_count--;
+	membar(StoreLoad);
+	csa->csa_state = CPU_BOOTSTRAP;
+	while (csa->csa_count != 0)
+		;
+
+	if (smp_cpus == mp_ncpus)
+		atomic_store_rel_int(&smp_started, 1);
+
+	/* Start per-CPU event timers. */
+	cpu_initclocks_ap();
+
+	/* Ok, now enter the scheduler. */
+	sched_throw(NULL);
+}
+
+void
+cpu_mp_shutdown(void)
+{
+	cpuset_t cpus;
+	int i;
+
+	critical_enter();
+	shutdown_cpus = all_cpus;
+	CPU_CLR(PCPU_GET(cpuid), &shutdown_cpus);
+	cpus = shutdown_cpus;
+
+	/* XXX: Stop all the CPUs which aren't already. */
+	if (CPU_CMP(&stopped_cpus, &cpus)) {
+
+		/* cpus is just a flat "on" mask without curcpu. */
+		CPU_NAND(&cpus, &stopped_cpus);
+		stop_cpus(cpus);
+	}
+	i = 0;
+	while (!CPU_EMPTY(&shutdown_cpus)) {
+		if (i++ > 100000) {
+			printf("timeout shutting down CPUs.\n");
+			break;
+		}
+	}
+	critical_exit();
+}
+
+static void
+cpu_ipi_ast(struct trapframe *tf __unused)
+{
+
+}
+
+static void
+cpu_ipi_stop(struct trapframe *tf __unused)
+{
+	u_int cpuid;
+
+	CTR2(KTR_SMP, "%s: stopped %d", __func__, curcpu);
+	sched_pin();
+	savectx(&stoppcbs[curcpu]);
+	cpuid = PCPU_GET(cpuid);
+	CPU_SET_ATOMIC(cpuid, &stopped_cpus);
+	while (!CPU_ISSET(cpuid, &started_cpus)) {
+		if (CPU_ISSET(cpuid, &shutdown_cpus)) {
+			CPU_CLR_ATOMIC(cpuid, &shutdown_cpus);
+			(void)intr_disable();
+			for (;;)
+				;
+		}
+	}
+	CPU_CLR_ATOMIC(cpuid, &started_cpus);
+	CPU_CLR_ATOMIC(cpuid, &stopped_cpus);
+	sched_unpin();
+	CTR2(KTR_SMP, "%s: restarted %d", __func__, curcpu);
+}
+
+static void
+cpu_ipi_preempt(struct trapframe *tf __unused)
+{
+
+	sched_preempt(curthread);
+}
+
+static void
+cpu_ipi_hardclock(struct trapframe *tf)
+{
+	struct trapframe *oldframe;
+	struct thread *td;
+
+	critical_enter();
+	td = curthread;
+	td->td_intr_nesting_level++;
+	oldframe = td->td_intr_frame;
+	td->td_intr_frame = tf;
+	hardclockintr();
+	td->td_intr_frame = oldframe;
+	td->td_intr_nesting_level--;
+	critical_exit();
+}
+
+static void
+spitfire_ipi_selected(cpuset_t cpus, u_long d0, u_long d1, u_long d2)
+{
+	u_int cpu;
+
+	while ((cpu = CPU_FFS(&cpus)) != 0) {
+		cpu--;
+		CPU_CLR(cpu, &cpus);
+		spitfire_ipi_single(cpu, d0, d1, d2);
+	}
+}
+
+static void
+spitfire_ipi_single(u_int cpu, u_long d0, u_long d1, u_long d2)
+{
+	register_t s;
+	u_long ids;
+	u_int mid;
+	int i;
+
+	mtx_assert(&ipi_mtx, MA_OWNED);
+	KASSERT(cpu != curcpu, ("%s: CPU can't IPI itself", __func__));
+	KASSERT((ldxa(0, ASI_INTR_DISPATCH_STATUS) & IDR_BUSY) == 0,
+	    ("%s: outstanding dispatch", __func__));
+
+	mid = cpuid_to_mid[cpu];
+	for (i = 0; i < IPI_RETRIES; i++) {
+		s = intr_disable();
+		stxa(AA_SDB_INTR_D0, ASI_SDB_INTR_W, d0);
+		stxa(AA_SDB_INTR_D1, ASI_SDB_INTR_W, d1);
+		stxa(AA_SDB_INTR_D2, ASI_SDB_INTR_W, d2);
+		membar(Sync);
+		stxa(AA_INTR_SEND | (mid << IDC_ITID_SHIFT),
+		    ASI_SDB_INTR_W, 0);
+		/*
+		 * Workaround for SpitFire erratum #54; do a dummy read
+		 * from a SDB internal register before the MEMBAR #Sync
+		 * for the write to ASI_SDB_INTR_W (requiring another
+		 * MEMBAR #Sync in order to make sure the write has
+		 * occurred before the load).
+		 */
+		membar(Sync);
+		(void)ldxa(AA_SDB_CNTL_HIGH, ASI_SDB_CONTROL_R);
+		membar(Sync);
+		while (((ids = ldxa(0, ASI_INTR_DISPATCH_STATUS)) &
+		    IDR_BUSY) != 0)
+			;
+		intr_restore(s);
+		if ((ids & (IDR_BUSY | IDR_NACK)) == 0)
+			return;
+	}
+	if (kdb_active != 0 || panicstr != NULL)
+		printf("%s: couldn't send IPI to module 0x%u\n",
+		    __func__, mid);
+	else
+		panic("%s: couldn't send IPI to module 0x%u",
+		    __func__, mid);
+}
+
+static void
+cheetah_ipi_single(u_int cpu, u_long d0, u_long d1, u_long d2)
+{
+	register_t s;
+	u_long ids;
+	u_int mid;
+	int i;
+
+	mtx_assert(&ipi_mtx, MA_OWNED);
+	KASSERT(cpu != curcpu, ("%s: CPU can't IPI itself", __func__));
+	KASSERT((ldxa(0, ASI_INTR_DISPATCH_STATUS) &
+	    IDR_CHEETAH_ALL_BUSY) == 0,
+	    ("%s: outstanding dispatch", __func__));
+
+	mid = cpuid_to_mid[cpu];
+	for (i = 0; i < IPI_RETRIES; i++) {
+		s = intr_disable();
+		stxa(AA_SDB_INTR_D0, ASI_SDB_INTR_W, d0);
+		stxa(AA_SDB_INTR_D1, ASI_SDB_INTR_W, d1);
+		stxa(AA_SDB_INTR_D2, ASI_SDB_INTR_W, d2);
+		membar(Sync);
+		stxa(AA_INTR_SEND | (mid << IDC_ITID_SHIFT),
+		    ASI_SDB_INTR_W, 0);
+		membar(Sync);
+		while (((ids = ldxa(0, ASI_INTR_DISPATCH_STATUS)) &
+		    IDR_BUSY) != 0)
+			;
+		intr_restore(s);
+		if ((ids & (IDR_BUSY | IDR_NACK)) == 0)
+			return;
+	}
+	if (kdb_active != 0 || panicstr != NULL)
+		printf("%s: couldn't send IPI to module 0x%u\n",
+		    __func__, mid);
+	else
+		panic("%s: couldn't send IPI to module 0x%u",
+		    __func__, mid);
+}
+
+static void
+cheetah_ipi_selected(cpuset_t cpus, u_long d0, u_long d1, u_long d2)
+{
+	register_t s;
+	u_long ids;
+	u_int bnp;
+	u_int cpu;
+	int i;
+
+	mtx_assert(&ipi_mtx, MA_OWNED);
+	KASSERT(!CPU_EMPTY(&cpus), ("%s: no CPUs to IPI", __func__));
+	KASSERT(!CPU_ISSET(curcpu, &cpus), ("%s: CPU can't IPI itself",
+	    __func__));
+	KASSERT((ldxa(0, ASI_INTR_DISPATCH_STATUS) &
+	    IDR_CHEETAH_ALL_BUSY) == 0,
+	    ("%s: outstanding dispatch", __func__));
+
+	ids = 0;
+	for (i = 0; i < IPI_RETRIES * smp_cpus; i++) {
+		s = intr_disable();
+		stxa(AA_SDB_INTR_D0, ASI_SDB_INTR_W, d0);
+		stxa(AA_SDB_INTR_D1, ASI_SDB_INTR_W, d1);
+		stxa(AA_SDB_INTR_D2, ASI_SDB_INTR_W, d2);
+		membar(Sync);
+		bnp = 0;
+		for (cpu = 0; cpu < smp_cpus; cpu++) {
+			if (CPU_ISSET(cpu, &cpus)) {
+				stxa(AA_INTR_SEND | (cpuid_to_mid[cpu] <<
+				    IDC_ITID_SHIFT) | bnp << IDC_BN_SHIFT,
+				    ASI_SDB_INTR_W, 0);
+				membar(Sync);
+				bnp++;
+				if (bnp == IDR_CHEETAH_MAX_BN_PAIRS)
+					break;
+			}
+		}
+		while (((ids = ldxa(0, ASI_INTR_DISPATCH_STATUS)) &
+		    IDR_CHEETAH_ALL_BUSY) != 0)
+			;
+		intr_restore(s);
+		bnp = 0;
+		for (cpu = 0; cpu < smp_cpus; cpu++) {
+			if (CPU_ISSET(cpu, &cpus)) {
+				if ((ids & (IDR_NACK << (2 * bnp))) == 0)
+					CPU_CLR(cpu, &cpus);
+				bnp++;
+			}
+		}
+		if (CPU_EMPTY(&cpus))
+			return;
+	}
+	if (kdb_active != 0 || panicstr != NULL)
+		printf("%s: couldn't send IPI (cpus=%s ids=0x%lu)\n",
+		    __func__, cpusetobj_strprint(ipi_pbuf, &cpus), ids);
+	else
+		panic("%s: couldn't send IPI (cpus=%s ids=0x%lu)",
+		    __func__, cpusetobj_strprint(ipi_pbuf, &cpus), ids);
+}
+
+static void
+jalapeno_ipi_single(u_int cpu, u_long d0, u_long d1, u_long d2)
+{
+	register_t s;
+	u_long ids;
+	u_int busy, busynack, mid;
+	int i;
+
+	mtx_assert(&ipi_mtx, MA_OWNED);
+	KASSERT(cpu != curcpu, ("%s: CPU can't IPI itself", __func__));
+	KASSERT((ldxa(0, ASI_INTR_DISPATCH_STATUS) &
+	    IDR_CHEETAH_ALL_BUSY) == 0,
+	    ("%s: outstanding dispatch", __func__));
+
+	mid = cpuid_to_mid[cpu];
+	busy = IDR_BUSY << (2 * mid);
+	busynack = (IDR_BUSY | IDR_NACK) << (2 * mid);
+	for (i = 0; i < IPI_RETRIES; i++) {
+		s = intr_disable();
+		stxa(AA_SDB_INTR_D0, ASI_SDB_INTR_W, d0);
+		stxa(AA_SDB_INTR_D1, ASI_SDB_INTR_W, d1);
+		stxa(AA_SDB_INTR_D2, ASI_SDB_INTR_W, d2);
+		membar(Sync);
+		stxa(AA_INTR_SEND | (mid << IDC_ITID_SHIFT),
+		    ASI_SDB_INTR_W, 0);
+		membar(Sync);
+		while (((ids = ldxa(0, ASI_INTR_DISPATCH_STATUS)) &
+		    busy) != 0)
+			;
+		intr_restore(s);
+		if ((ids & busynack) == 0)
+			return;
+	}
+	if (kdb_active != 0 || panicstr != NULL)
+		printf("%s: couldn't send IPI to module 0x%u\n",
+		    __func__, mid);
+	else
+		panic("%s: couldn't send IPI to module 0x%u",
+		    __func__, mid);
+}
+
+static void
+jalapeno_ipi_selected(cpuset_t cpus, u_long d0, u_long d1, u_long d2)
+{
+	register_t s;
+	u_long ids;
+	u_int cpu;
+	int i;
+
+	mtx_assert(&ipi_mtx, MA_OWNED);
+	KASSERT(!CPU_EMPTY(&cpus), ("%s: no CPUs to IPI", __func__));
+	KASSERT(!CPU_ISSET(curcpu, &cpus), ("%s: CPU can't IPI itself",
+	    __func__));
+	KASSERT((ldxa(0, ASI_INTR_DISPATCH_STATUS) &
+	    IDR_CHEETAH_ALL_BUSY) == 0,
+	    ("%s: outstanding dispatch", __func__));
+
+	ids = 0;
+	for (i = 0; i < IPI_RETRIES * smp_cpus; i++) {
+		s = intr_disable();
+		stxa(AA_SDB_INTR_D0, ASI_SDB_INTR_W, d0);
+		stxa(AA_SDB_INTR_D1, ASI_SDB_INTR_W, d1);
+		stxa(AA_SDB_INTR_D2, ASI_SDB_INTR_W, d2);
+		membar(Sync);
+		for (cpu = 0; cpu < smp_cpus; cpu++) {
+			if (CPU_ISSET(cpu, &cpus)) {
+				stxa(AA_INTR_SEND | (cpuid_to_mid[cpu] <<
+				    IDC_ITID_SHIFT), ASI_SDB_INTR_W, 0);
+				membar(Sync);
+			}
+		}
+		while (((ids = ldxa(0, ASI_INTR_DISPATCH_STATUS)) &
+		    IDR_CHEETAH_ALL_BUSY) != 0)
+			;
+		intr_restore(s);
+		if ((ids &
+		    (IDR_CHEETAH_ALL_BUSY | IDR_CHEETAH_ALL_NACK)) == 0)
+			return;
+		for (cpu = 0; cpu < smp_cpus; cpu++)
+			if (CPU_ISSET(cpu, &cpus))
+				if ((ids & (IDR_NACK <<
+				    (2 * cpuid_to_mid[cpu]))) == 0)
+					CPU_CLR(cpu, &cpus);
+	}
+	if (kdb_active != 0 || panicstr != NULL)
+		printf("%s: couldn't send IPI (cpus=%s ids=0x%lu)\n",
+		    __func__, cpusetobj_strprint(ipi_pbuf, &cpus), ids);
+	else
+		panic("%s: couldn't send IPI (cpus=%s ids=0x%lu)",
+		    __func__, cpusetobj_strprint(ipi_pbuf, &cpus), ids);
+}


Property changes on: trunk/sys/sparc64/sparc64/mp_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/nexus.c
===================================================================
--- trunk/sys/sparc64/sparc64/nexus.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/nexus.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,604 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 1998 Massachusetts Institute of Technology
+ * Copyright 2001 by Thomas Moestl <tmm at FreeBSD.org>.
+ * Copyright 2006 by Marius Strobl <marius at FreeBSD.org>.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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: FreeBSD: src/sys/i386/i386/nexus.c,v 1.43 2001/02/09
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/nexus.c 227848 2011-11-22 21:55:40Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/pcpu.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/bus_common.h>
+#include <machine/intr_machdep.h>
+#include <machine/nexusvar.h>
+#include <machine/ofw_nexus.h>
+#include <machine/resource.h>
+#include <machine/ver.h>
+
+#include <sys/rman.h>
+
+/*
+ * The nexus (which is a pseudo-bus actually) iterates over the nodes that
+ * hang from the Open Firmware root node and adds them as devices to this bus
+ * (except some special nodes which are excluded) so that drivers can be
+ * attached to them.
+ *
+ * Additionally, interrupt setup/teardown and some resource management are
+ * done at this level.
+ *
+ * Maybe this code should get into dev/ofw to some extent, as some of it should
+ * work for all Open Firmware based machines...
+ */
+
+struct nexus_devinfo {
+	struct ofw_bus_devinfo	ndi_obdinfo;
+	struct resource_list	ndi_rl;
+};
+
+struct nexus_softc {
+	struct rman	sc_intr_rman;
+	struct rman	sc_mem_rman;
+};
+
+static device_probe_t nexus_probe;
+static device_attach_t nexus_attach;
+static bus_print_child_t nexus_print_child;
+static bus_add_child_t nexus_add_child;
+static bus_probe_nomatch_t nexus_probe_nomatch;
+static bus_setup_intr_t nexus_setup_intr;
+static bus_teardown_intr_t nexus_teardown_intr;
+static bus_alloc_resource_t nexus_alloc_resource;
+static bus_activate_resource_t nexus_activate_resource;
+static bus_deactivate_resource_t nexus_deactivate_resource;
+static bus_adjust_resource_t nexus_adjust_resource;
+static bus_release_resource_t nexus_release_resource;
+static bus_get_resource_list_t nexus_get_resource_list;
+#ifdef SMP
+static bus_bind_intr_t nexus_bind_intr;
+#endif
+static bus_describe_intr_t nexus_describe_intr;
+static bus_get_dma_tag_t nexus_get_dma_tag;
+static ofw_bus_get_devinfo_t nexus_get_devinfo;
+
+static int nexus_inlist(const char *, const char *const *);
+static struct nexus_devinfo * nexus_setup_dinfo(device_t, phandle_t);
+static void nexus_destroy_dinfo(struct nexus_devinfo *);
+static int nexus_print_res(struct nexus_devinfo *);
+
+static device_method_t nexus_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		nexus_probe),
+	DEVMETHOD(device_attach,	nexus_attach),
+	DEVMETHOD(device_detach,	bus_generic_detach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	nexus_print_child),
+	DEVMETHOD(bus_probe_nomatch,	nexus_probe_nomatch),
+	DEVMETHOD(bus_read_ivar,	bus_generic_read_ivar),
+	DEVMETHOD(bus_write_ivar,	bus_generic_write_ivar),
+	DEVMETHOD(bus_add_child,	nexus_add_child),
+	DEVMETHOD(bus_alloc_resource,	nexus_alloc_resource),
+	DEVMETHOD(bus_activate_resource,	nexus_activate_resource),
+	DEVMETHOD(bus_deactivate_resource,	nexus_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	nexus_adjust_resource),
+	DEVMETHOD(bus_release_resource,	nexus_release_resource),
+	DEVMETHOD(bus_setup_intr,	nexus_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	nexus_teardown_intr),
+	DEVMETHOD(bus_set_resource,	bus_generic_rl_set_resource),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	DEVMETHOD(bus_get_resource_list, nexus_get_resource_list),
+#ifdef SMP
+	DEVMETHOD(bus_bind_intr,	nexus_bind_intr),
+#endif
+	DEVMETHOD(bus_describe_intr,	nexus_describe_intr),
+	DEVMETHOD(bus_get_dma_tag,	nexus_get_dma_tag),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	nexus_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	DEVMETHOD_END
+};
+
+static devclass_t nexus_devclass;
+
+DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, sizeof(struct nexus_softc));
+EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0,
+    BUS_PASS_BUS);
+MODULE_VERSION(nexus, 1);
+
+static const char *const nexus_excl_name[] = {
+	"FJSV,system",
+	"aliases",
+	"associations",
+	"chosen",
+	"cmp",
+	"counter-timer",	/* No separate device; handled by psycho/sbus */
+	"failsafe",
+	"memory",
+	"openprom",
+	"options",
+	"packages",
+	"physical-memory",
+	"rsc",
+	"sgcn",
+	"todsg",
+	"virtual-memory",
+	NULL
+};
+
+static const char *const nexus_excl_type[] = {
+	"core",
+	"cpu",
+	NULL
+};
+
+extern struct bus_space_tag nexus_bustag;
+extern struct bus_dma_tag nexus_dmatag;
+
+static int
+nexus_inlist(const char *name, const char *const *list)
+{
+	int i;
+
+	if (name == NULL)
+		return (0);
+	for (i = 0; list[i] != NULL; i++)
+		if (strcmp(name, list[i]) == 0)
+			return (1);
+	return (0);
+}
+
+#define	NEXUS_EXCLUDED(name, type)					\
+	(nexus_inlist((name), nexus_excl_name) ||			\
+	((type) != NULL && nexus_inlist((type), nexus_excl_type)))
+
+static int
+nexus_probe(device_t dev)
+{
+
+	/* Nexus does always match. */
+	device_set_desc(dev, "Open Firmware Nexus device");
+	return (0);
+}
+
+static int
+nexus_attach(device_t dev)
+{
+	struct nexus_devinfo *ndi;
+	struct nexus_softc *sc;
+	device_t cdev;
+	phandle_t node;
+
+	if (strcmp(device_get_name(device_get_parent(dev)), "root") == 0) {
+		node = OF_peer(0);
+		if (node == -1)
+			panic("%s: OF_peer failed.", __func__);
+
+		sc = device_get_softc(dev);
+		sc->sc_intr_rman.rm_type = RMAN_ARRAY;
+		sc->sc_intr_rman.rm_descr = "Interrupts";
+		sc->sc_mem_rman.rm_type = RMAN_ARRAY;
+		sc->sc_mem_rman.rm_descr = "Device Memory";
+		if (rman_init(&sc->sc_intr_rman) != 0 ||
+		    rman_init(&sc->sc_mem_rman) != 0 ||
+		    rman_manage_region(&sc->sc_intr_rman, 0,
+		    IV_MAX - 1) != 0 ||
+		    rman_manage_region(&sc->sc_mem_rman, 0ULL, ~0ULL) != 0)
+			panic("%s: failed to set up rmans.", __func__);
+	} else
+		node = ofw_bus_get_node(dev);
+
+	/*
+	 * Allow devices to identify.
+	 */
+	bus_generic_probe(dev);
+
+	/*
+	 * Now walk the OFW tree and attach top-level devices.
+	 */
+	for (node = OF_child(node); node > 0; node = OF_peer(node)) {
+		if ((ndi = nexus_setup_dinfo(dev, node)) == NULL)
+			continue;
+		cdev = device_add_child(dev, NULL, -1);
+		if (cdev == NULL) {
+			device_printf(dev, "<%s>: device_add_child failed\n",
+			    ndi->ndi_obdinfo.obd_name);
+			nexus_destroy_dinfo(ndi);
+			continue;
+		}
+		device_set_ivars(cdev, ndi);
+	}
+	return (bus_generic_attach(dev));
+}
+
+static device_t
+nexus_add_child(device_t dev, u_int order, const char *name, int unit)
+{
+	device_t cdev;
+	struct nexus_devinfo *ndi;
+
+	cdev = device_add_child_ordered(dev, order, name, unit);
+	if (cdev == NULL)
+		return (NULL);
+
+	ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO);
+	ndi->ndi_obdinfo.obd_node = -1;
+	ndi->ndi_obdinfo.obd_name = strdup(name, M_OFWPROP);
+	resource_list_init(&ndi->ndi_rl);
+	device_set_ivars(cdev, ndi);
+
+	return (cdev);
+}
+
+static int
+nexus_print_child(device_t bus, device_t child)
+{
+	int rv;
+
+	rv = bus_print_child_header(bus, child);
+	rv += nexus_print_res(device_get_ivars(child));
+	rv += bus_print_child_footer(bus, child);
+	return (rv);
+}
+
+static void
+nexus_probe_nomatch(device_t bus, device_t child)
+{
+	const char *type;
+
+	device_printf(bus, "<%s>", ofw_bus_get_name(child));
+	nexus_print_res(device_get_ivars(child));
+	type = ofw_bus_get_type(child);
+	printf(" type %s (no driver attached)\n",
+	    type != NULL ? type : "unknown");
+}
+
+static int
+nexus_setup_intr(device_t bus __unused, device_t child, struct resource *r,
+    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
+    void **cookiep)
+{
+	int error;
+
+	if (r == NULL)
+		panic("%s: NULL interrupt resource!", __func__);
+
+	if ((rman_get_flags(r) & RF_SHAREABLE) == 0)
+		flags |= INTR_EXCL;
+
+	/* We depend here on rman_activate_resource() being idempotent. */
+	error = rman_activate_resource(r);
+	if (error)
+		return (error);
+
+	error = inthand_add(device_get_nameunit(child), rman_get_start(r),
+	    filt, intr, arg, flags, cookiep);
+
+	/*
+	 * XXX in case of the AFB/FFB interrupt and a Psycho, Sabre or U2S
+	 * bridge enable the interrupt in the respective bridge.
+	 */
+
+	return (error);
+}
+
+static int
+nexus_teardown_intr(device_t bus __unused, device_t child __unused,
+    struct resource *r, void *ih)
+{
+
+	inthand_remove(rman_get_start(r), ih);
+	return (0);
+}
+
+#ifdef SMP
+static int
+nexus_bind_intr(device_t bus __unused, device_t child __unused,
+    struct resource *r, int cpu)
+{
+
+	return (intr_bind(rman_get_start(r), cpu));
+}
+#endif
+
+static int
+nexus_describe_intr(device_t bus __unused, device_t child __unused,
+    struct resource *r, void *cookie, const char *descr)
+{
+
+	return (intr_describe(rman_get_start(r), cookie, descr));
+}
+
+static struct resource *
+nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct nexus_softc *sc;
+	struct rman *rm;
+	struct resource *rv;
+	struct resource_list_entry *rle;
+	device_t nexus;
+	int isdefault, passthrough;
+
+	isdefault = (start == 0UL && end == ~0UL);
+	passthrough = (device_get_parent(child) != bus);
+	nexus = bus;
+	while (strcmp(device_get_name(device_get_parent(nexus)), "root") != 0)
+		nexus = device_get_parent(nexus);
+	sc = device_get_softc(nexus);
+	rle = NULL;
+
+	if (!passthrough) {
+		rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child),
+		    type, *rid);
+		if (rle == NULL)
+			return (NULL);
+		if (rle->res != NULL)
+			panic("%s: resource entry is busy", __func__);
+		if (isdefault) {
+			start = rle->start;
+			count = ulmax(count, rle->count);
+			end = ulmax(rle->end, start + count - 1);
+		}
+	}
+
+	switch (type) {
+	case SYS_RES_IRQ:
+		rm = &sc->sc_intr_rman;
+		break;
+	case SYS_RES_MEMORY:
+		rm = &sc->sc_mem_rman;
+		break;
+	default:
+		return (NULL);
+	}
+
+	rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
+	    child);
+	if (rv == NULL)
+		return (NULL);
+	rman_set_rid(rv, *rid);
+
+	if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
+	    *rid, rv) != 0) {
+		rman_release_resource(rv);
+		return (NULL);
+	}
+
+	if (!passthrough) {
+		rle->res = rv;
+		rle->start = rman_get_start(rv);
+		rle->end = rman_get_end(rv);
+		rle->count = rle->end - rle->start + 1;
+	}
+
+	return (rv);
+}
+
+static int
+nexus_activate_resource(device_t bus __unused, device_t child __unused,
+    int type, int rid __unused, struct resource *r)
+{
+
+	if (type == SYS_RES_MEMORY) {
+		rman_set_bustag(r, &nexus_bustag);
+		rman_set_bushandle(r, rman_get_start(r));
+	}
+	return (rman_activate_resource(r));
+}
+
+static int
+nexus_deactivate_resource(device_t bus __unused, device_t child __unused,
+    int type __unused, int rid __unused, struct resource *r)
+{
+
+	return (rman_deactivate_resource(r));
+}
+
+static int
+nexus_adjust_resource(device_t bus, device_t child __unused, int type,
+    struct resource *r, u_long start, u_long end)
+{
+	struct nexus_softc *sc;
+	struct rman *rm;
+	device_t nexus;
+
+	nexus = bus;
+	while (strcmp(device_get_name(device_get_parent(nexus)), "root") != 0)
+		nexus = device_get_parent(nexus);
+	sc = device_get_softc(nexus);
+	switch (type) {
+	case SYS_RES_IRQ:
+		rm = &sc->sc_intr_rman;
+		break;
+	case SYS_RES_MEMORY:
+		rm = &sc->sc_mem_rman;
+		break;
+	default:
+		return (EINVAL);
+	}
+	if (rm == NULL)
+		return (ENXIO);
+	if (rman_is_region_manager(r, rm) == 0)
+		return (EINVAL);
+	return (rman_adjust_resource(r, start, end));
+}
+
+static int
+nexus_release_resource(device_t bus __unused, device_t child, int type,
+    int rid, struct resource *r)
+{
+	int error;
+
+	if ((rman_get_flags(r) & RF_ACTIVE) != 0) {
+		error = bus_deactivate_resource(child, type, rid, r);
+		if (error)
+			return (error);
+	}
+	return (rman_release_resource(r));
+}
+
+static struct resource_list *
+nexus_get_resource_list(device_t bus __unused, device_t child)
+{
+	struct nexus_devinfo *ndi;
+
+	ndi = device_get_ivars(child);
+	return (&ndi->ndi_rl);
+}
+
+static bus_dma_tag_t
+nexus_get_dma_tag(device_t bus __unused, device_t child __unused)
+{
+
+	return (&nexus_dmatag);
+}
+
+static const struct ofw_bus_devinfo *
+nexus_get_devinfo(device_t bus __unused, device_t child)
+{
+	struct nexus_devinfo *ndi;
+
+	ndi = device_get_ivars(child);
+	return (&ndi->ndi_obdinfo);
+}
+
+static struct nexus_devinfo *
+nexus_setup_dinfo(device_t dev, phandle_t node)
+{
+	struct nexus_devinfo *ndi;
+	struct nexus_regs *reg;
+	bus_addr_t phys;
+	bus_size_t size;
+	uint32_t ign;
+	uint32_t *intr;
+	int i;
+	int nintr;
+	int nreg;
+
+	ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO);
+	if (ofw_bus_gen_setup_devinfo(&ndi->ndi_obdinfo, node) != 0) {
+		free(ndi, M_DEVBUF);
+		return (NULL);
+	}
+	if (NEXUS_EXCLUDED(ndi->ndi_obdinfo.obd_name,
+	    ndi->ndi_obdinfo.obd_type)) {
+		ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo);
+		free(ndi, M_DEVBUF);
+		return (NULL);
+	}
+	resource_list_init(&ndi->ndi_rl);
+	nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
+	if (nreg == -1) {
+		device_printf(dev, "<%s>: incomplete\n",
+		    ndi->ndi_obdinfo.obd_name);
+		goto fail;
+	}
+	for (i = 0; i < nreg; i++) {
+		phys = NEXUS_REG_PHYS(&reg[i]);
+		size = NEXUS_REG_SIZE(&reg[i]);
+		/* Skip the dummy reg property of glue devices like ssm(4). */
+		if (size != 0)
+			resource_list_add(&ndi->ndi_rl, SYS_RES_MEMORY, i,
+			    phys, phys + size - 1, size);
+	}
+	free(reg, M_OFWPROP);
+
+	nintr = OF_getprop_alloc(node, "interrupts",  sizeof(*intr),
+	    (void **)&intr);
+	if (nintr > 0) {
+		if (OF_getprop(node, PCPU_GET(impl) < CPU_IMPL_ULTRASPARCIII ?
+		    "upa-portid" : "portid", &ign, sizeof(ign)) <= 0) {
+			device_printf(dev, "<%s>: could not determine portid\n",
+			    ndi->ndi_obdinfo.obd_name);
+			free(intr, M_OFWPROP);
+			goto fail;
+		}
+
+		/* XXX 7-bit MID on Starfire */
+		ign = (ign << INTMAP_IGN_SHIFT) & INTMAP_IGN_MASK;
+		for (i = 0; i < nintr; i++) {
+			intr[i] |= ign;
+			resource_list_add(&ndi->ndi_rl, SYS_RES_IRQ, i, intr[i],
+			    intr[i], 1);
+		}
+		free(intr, M_OFWPROP);
+	}
+
+	return (ndi);
+
+ fail:
+	nexus_destroy_dinfo(ndi);
+	return (NULL);
+}
+
+static void
+nexus_destroy_dinfo(struct nexus_devinfo *ndi)
+{
+
+	resource_list_free(&ndi->ndi_rl);
+	ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo);
+	free(ndi, M_DEVBUF);
+}
+
+static int
+nexus_print_res(struct nexus_devinfo *ndi)
+{
+	int rv;
+
+	rv = 0;
+	rv += resource_list_print_type(&ndi->ndi_rl, "mem", SYS_RES_MEMORY,
+	    "%#lx");
+	rv += resource_list_print_type(&ndi->ndi_rl, "irq", SYS_RES_IRQ,
+	    "%ld");
+	return (rv);
+}


Property changes on: trunk/sys/sparc64/sparc64/nexus.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/ofw_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/ofw_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/ofw_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,293 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 by Thomas Moestl <tmm at FreeBSD.org>.
+ * Copyright (c) 2005 - 2010 by Marius Strobl <marius at 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, 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 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/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/ofw_machdep.c 230632 2012-01-27 22:35:53Z marius $");
+
+/*
+ * Some Open Firmware helper functions that are likely machine dependent.
+ */
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/systm.h>
+
+#include <net/ethernet.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/idprom.h>
+#include <machine/ofw_machdep.h>
+#include <machine/stdarg.h>
+
+void
+OF_getetheraddr(device_t dev, u_char *addr)
+{
+	char buf[sizeof("true")];
+	phandle_t node;
+	struct idprom idp;
+
+	if ((node = OF_finddevice("/options")) != -1 &&
+	    OF_getprop(node, "local-mac-address?", buf, sizeof(buf)) > 0) {
+		buf[sizeof(buf) - 1] = '\0';
+		if (strcmp(buf, "true") == 0 &&
+		    (node = ofw_bus_get_node(dev)) > 0 &&
+		    OF_getprop(node, "local-mac-address", addr,
+		    ETHER_ADDR_LEN) == ETHER_ADDR_LEN)
+			return;
+	}
+
+	node = OF_peer(0);
+	if (node <= 0 || OF_getprop(node, "idprom", &idp, sizeof(idp)) == -1)
+		panic("Could not determine the machine Ethernet address");
+	bcopy(&idp.id_ether, addr, ETHER_ADDR_LEN);
+}
+
+u_int
+OF_getscsinitid(device_t dev)
+{
+	phandle_t node;
+	uint32_t id;
+
+	for (node = ofw_bus_get_node(dev); node != 0; node = OF_parent(node))
+		if (OF_getprop(node, "scsi-initiator-id", &id,
+		    sizeof(id)) > 0)
+			return (id);
+	return (7);
+}
+
+void
+OF_panic(const char *fmt, ...)
+{
+	char buf[256];
+	va_list ap;
+
+	va_start(ap, fmt);
+	(void)vsnprintf(buf, sizeof(buf), fmt, ap);
+	OF_printf("OF_panic: %s\n", buf);
+	va_end(ap);
+	OF_exit();
+}
+
+static __inline uint32_t
+phys_hi_mask_space(const char *bus, uint32_t phys_hi)
+{
+
+	if (strcmp(bus, "ebus") == 0 || strcmp(bus, "isa") == 0)
+		phys_hi &= 0x1;
+	else if (strcmp(bus, "pci") == 0)
+		phys_hi &= OFW_PCI_PHYS_HI_SPACEMASK;
+	/* The phys.hi cells of the other busses only contain space bits. */
+	return (phys_hi);
+}
+
+/*
+ * Return the physical address and the bus space to use for a node
+ * referenced by its package handle and the index of the register bank
+ * to decode.  Intended to be used to together with sparc64_fake_bustag()
+ * by console drivers in early boot only.
+ * Works by mapping the address of the node's bank given in the address
+ * space of its parent upward in the device tree at each bridge along the
+ * path.
+ * Currently only really deals with max. 64-bit addresses, i.e. addresses
+ * consisting of max. 2 phys cells (phys.hi and phys.lo).  If we encounter
+ * a 3 phys cells address (as with PCI addresses) we assume phys.hi can
+ * be ignored except for the space bits (generally contained in phys.hi)
+ * and treat phys.mid as phys.hi.
+ */
+int
+OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
+{
+	char name[32];
+	uint64_t cend, cstart, end, phys, pphys, sz, start;
+	pcell_t addrc, szc, paddrc;
+	phandle_t bus, lbus, pbus;
+	uint32_t banks[10 * 5];	/* 10 PCI banks */
+	uint32_t cspc, pspc, spc;
+	int i, j, nbank;
+
+	/*
+	 * In general the addresses are contained in the "reg" property
+	 * of a node.  The first address in the "reg" property of a PCI
+	 * node however is the address of its configuration registers in
+	 * the configuration space of the host bridge.  Additional entries
+	 * denote the memory and I/O addresses.  For relocatable addresses
+	 * the "reg" property contains the BAR, for non-relocatable
+	 * addresses it contains the absolute PCI address.  The PCI-only
+	 * "assigned-addresses" property however always contains the
+	 * absolute PCI addresses.
+	 * The "assigned-addresses" and "reg" properties are arrays of
+	 * address structures consisting of #address-cells 32-bit phys
+	 * cells and #size-cells 32-bit size cells.  If a parent lacks
+	 * the "#address-cells" or "#size-cells" property the default
+	 * for #address-cells to use is 2 and for #size-cells 1.
+	 */
+	bus = OF_parent(node);
+	if (bus == 0)
+		return (ENXIO);
+	if (OF_getprop(bus, "name", name, sizeof(name)) == -1)
+		return (ENXIO);
+	name[sizeof(name) - 1] = '\0';
+	if (OF_getprop(bus, "#address-cells", &addrc, sizeof(addrc)) == -1)
+		addrc = 2;
+	if (OF_getprop(bus, "#size-cells", &szc, sizeof(szc)) == -1)
+		szc = 1;
+	if (addrc < 2 || addrc > 3 || szc < 1 || szc > 2)
+		return (ENXIO);
+	if (strcmp(name, "pci") == 0) {
+		if (addrc > 3)
+			return (ENXIO);
+		nbank = OF_getprop(node, "assigned-addresses", &banks,
+		    sizeof(banks));
+	} else {
+		if (addrc > 2)
+			return (ENXIO);
+		nbank = OF_getprop(node, "reg", &banks, sizeof(banks));
+	}
+	if (nbank == -1)
+		return (ENXIO);
+	nbank /= sizeof(banks[0]) * (addrc + szc);
+	if (bank < 0 || bank > nbank - 1)
+		return (ENXIO);
+	bank *= addrc + szc;
+	spc = phys_hi_mask_space(name, banks[bank]);
+	/* Skip the high cell for 3-cell addresses. */
+	bank += addrc - 2;
+	phys = 0;
+	for (i = 0; i < MIN(2, addrc); i++)
+		phys = ((uint64_t)phys << 32) | banks[bank++];
+	sz = 0;
+	for (i = 0; i < szc; i++)
+		sz = ((uint64_t)sz << 32) | banks[bank++];
+	start = phys;
+	end = phys + sz - 1;
+
+	/*
+	 * Map upward in the device tree at every bridge we encounter
+	 * using their "ranges" properties.
+	 * The "ranges" property of a bridge is an array of a structure
+	 * consisting of that bridge's #address-cells 32-bit child-phys
+	 * cells, its parent bridge #address-cells 32-bit parent-phys
+	 * cells and that bridge's #size-cells 32-bit size cells.
+	 * If a bridge doesn't have a "ranges" property no mapping is
+	 * necessary at that bridge.
+	 */
+	cspc = 0;
+	lbus = bus;
+	while ((pbus = OF_parent(bus)) != 0) {
+		if (OF_getprop(pbus, "#address-cells", &paddrc,
+		    sizeof(paddrc)) == -1)
+			paddrc = 2;
+		if (paddrc < 2 || paddrc > 3)
+			return (ENXIO);
+		nbank = OF_getprop(bus, "ranges", &banks, sizeof(banks));
+		if (nbank == -1) {
+			if (OF_getprop(pbus, "name", name, sizeof(name)) == -1)
+				return (ENXIO);
+			name[sizeof(name) - 1] = '\0';
+			goto skip;
+		}
+		if (OF_getprop(bus, "#size-cells", &szc, sizeof(szc)) == -1)
+			szc = 1;
+		if (szc < 1 || szc > 2)
+			return (ENXIO);
+		nbank /= sizeof(banks[0]) * (addrc + paddrc + szc);
+		bank = 0;
+		for (i = 0; i < nbank; i++) {
+			cspc = phys_hi_mask_space(name, banks[bank]);
+			if (cspc != spc) {
+				bank += addrc + paddrc + szc;
+				continue;
+			}
+			/* Skip the high cell for 3-cell addresses. */
+			bank += addrc - 2;
+			phys = 0;
+			for (j = 0; j < MIN(2, addrc); j++)
+				phys = ((uint64_t)phys << 32) | banks[bank++];
+			pspc = banks[bank];
+			/* Skip the high cell for 3-cell addresses. */
+			bank += paddrc - 2;
+			pphys = 0;
+			for (j = 0; j < MIN(2, paddrc); j++)
+				pphys =
+				    ((uint64_t)pphys << 32) | banks[bank++];
+			sz = 0;
+			for (j = 0; j < szc; j++)
+				sz = ((uint64_t)sz << 32) | banks[bank++];
+			cstart = phys;
+			cend = phys + sz - 1;
+			if (start < cstart || start > cend)
+				continue;
+			if (end < cstart || end > cend)
+				return (ENXIO);
+			if (OF_getprop(pbus, "name", name, sizeof(name)) == -1)
+				return (ENXIO);
+			name[sizeof(name) - 1] = '\0';
+			spc = phys_hi_mask_space(name, pspc);
+			start += pphys - cstart;
+			end += pphys - cstart;
+			break;
+		}
+		if (i == nbank)
+			return (ENXIO);
+		lbus = bus;
+ skip:
+		addrc = paddrc;
+		bus = pbus;
+	}
+
+	*addr = start;
+	/* Determine the bus space based on the last bus we mapped. */
+	if (OF_parent(lbus) == 0) {
+		*space = NEXUS_BUS_SPACE;
+		return (0);
+	}
+	if (OF_getprop(lbus, "name", name, sizeof(name)) == -1)
+		return (ENXIO);
+	name[sizeof(name) - 1] = '\0';
+	if (strcmp(name, "central") == 0 || strcmp(name, "ebus") == 0 ||
+	    strcmp(name, "upa") == 0) {
+		*space = NEXUS_BUS_SPACE;
+		return (0);
+	} else if (strcmp(name, "pci") == 0) {
+		switch (cspc) {
+		case OFW_PCI_PHYS_HI_SPACE_IO:
+			*space = PCI_IO_BUS_SPACE;
+			return (0);
+		case OFW_PCI_PHYS_HI_SPACE_MEM32:
+			*space = PCI_MEMORY_BUS_SPACE;
+			return (0);
+		}
+	} else if (strcmp(name, "sbus") == 0) {
+		*space = SBUS_BUS_SPACE;
+		return (0);
+	}
+	return (ENXIO);
+}


Property changes on: trunk/sys/sparc64/sparc64/ofw_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/pmap.c
===================================================================
--- trunk/sys/sparc64/sparc64/pmap.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/pmap.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,2287 @@
+/* $MidnightBSD$ */
+/*-
+ * 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.
+ *
+ * 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.
+ * 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
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/pmap.c 293853 2016-01-13 21:38:52Z marius $");
+
+/*
+ * Manages physical address maps.
+ *
+ * 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
+ * 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
+ * reduced protection operations until such time as they are actually
+ * necessary.  This module is given full information as to which processors
+ * are currently using which maps, and to when physical maps must be made
+ * correct.
+ */
+
+#include "opt_kstack_pages.h"
+#include "opt_pmap.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/msgbuf.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/smp.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#include <sys/vmmeter.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.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_phys.h>
+
+#include <machine/cache.h>
+#include <machine/frame.h>
+#include <machine/instr.h>
+#include <machine/md_var.h>
+#include <machine/metadata.h>
+#include <machine/ofw_mem.h>
+#include <machine/smp.h>
+#include <machine/tlb.h>
+#include <machine/tte.h>
+#include <machine/tsb.h>
+#include <machine/ver.h>
+
+/*
+ * Virtual address of message buffer
+ */
+struct msgbuf *msgbufp;
+
+/*
+ * Map of physical memory reagions
+ */
+vm_paddr_t phys_avail[128];
+static struct ofw_mem_region mra[128];
+struct ofw_mem_region sparc64_memreg[128];
+int sparc64_nmemreg;
+static struct ofw_map translations[128];
+static int translations_size;
+
+static vm_offset_t pmap_idle_map;
+static vm_offset_t pmap_temp_map_1;
+static vm_offset_t pmap_temp_map_2;
+
+/*
+ * First and last available kernel virtual addresses
+ */
+vm_offset_t virtual_avail;
+vm_offset_t virtual_end;
+vm_offset_t kernel_vm_end;
+
+vm_offset_t vm_max_kernel_address;
+
+/*
+ * Kernel pmap
+ */
+struct pmap kernel_pmap_store;
+
+struct rwlock_padalign tte_list_global_lock;
+
+/*
+ * Allocate physical memory for use in pmap_bootstrap.
+ */
+static vm_paddr_t pmap_bootstrap_alloc(vm_size_t size, uint32_t colors);
+
+static void pmap_bootstrap_set_tte(struct tte *tp, u_long vpn, u_long data);
+static void pmap_cache_remove(vm_page_t m, vm_offset_t va);
+static int pmap_protect_tte(struct pmap *pm1, struct pmap *pm2,
+    struct tte *tp, vm_offset_t va);
+static int pmap_unwire_tte(pmap_t pm, pmap_t pm2, struct tte *tp,
+    vm_offset_t va);
+
+/*
+ * Map the given physical page at the specified virtual address in the
+ * target pmap with the protection requested.  If specified the page
+ * will be wired down.
+ *
+ * The page queues and pmap must be locked.
+ */
+static int pmap_enter_locked(pmap_t pm, vm_offset_t va, vm_page_t m,
+    vm_prot_t prot, u_int flags, int8_t psind);
+
+extern int tl1_dmmu_miss_direct_patch_tsb_phys_1[];
+extern int tl1_dmmu_miss_direct_patch_tsb_phys_end_1[];
+extern int tl1_dmmu_miss_patch_asi_1[];
+extern int tl1_dmmu_miss_patch_quad_ldd_1[];
+extern int tl1_dmmu_miss_patch_tsb_1[];
+extern int tl1_dmmu_miss_patch_tsb_2[];
+extern int tl1_dmmu_miss_patch_tsb_mask_1[];
+extern int tl1_dmmu_miss_patch_tsb_mask_2[];
+extern int tl1_dmmu_prot_patch_asi_1[];
+extern int tl1_dmmu_prot_patch_quad_ldd_1[];
+extern int tl1_dmmu_prot_patch_tsb_1[];
+extern int tl1_dmmu_prot_patch_tsb_2[];
+extern int tl1_dmmu_prot_patch_tsb_mask_1[];
+extern int tl1_dmmu_prot_patch_tsb_mask_2[];
+extern int tl1_immu_miss_patch_asi_1[];
+extern int tl1_immu_miss_patch_quad_ldd_1[];
+extern int tl1_immu_miss_patch_tsb_1[];
+extern int tl1_immu_miss_patch_tsb_2[];
+extern int tl1_immu_miss_patch_tsb_mask_1[];
+extern int tl1_immu_miss_patch_tsb_mask_2[];
+
+/*
+ * If user pmap is processed with pmap_remove and with pmap_remove and the
+ * resident count drops to 0, there are no more pages to remove, so we
+ * need not continue.
+ */
+#define	PMAP_REMOVE_DONE(pm) \
+	((pm) != kernel_pmap && (pm)->pm_stats.resident_count == 0)
+
+/*
+ * The threshold (in bytes) above which tsb_foreach() is used in pmap_remove()
+ * and pmap_protect() instead of trying each virtual address.
+ */
+#define	PMAP_TSB_THRESH	((TSB_SIZE / 2) * PAGE_SIZE)
+
+SYSCTL_NODE(_debug, OID_AUTO, pmap_stats, CTLFLAG_RD, 0, "");
+
+PMAP_STATS_VAR(pmap_nenter);
+PMAP_STATS_VAR(pmap_nenter_update);
+PMAP_STATS_VAR(pmap_nenter_replace);
+PMAP_STATS_VAR(pmap_nenter_new);
+PMAP_STATS_VAR(pmap_nkenter);
+PMAP_STATS_VAR(pmap_nkenter_oc);
+PMAP_STATS_VAR(pmap_nkenter_stupid);
+PMAP_STATS_VAR(pmap_nkremove);
+PMAP_STATS_VAR(pmap_nqenter);
+PMAP_STATS_VAR(pmap_nqremove);
+PMAP_STATS_VAR(pmap_ncache_enter);
+PMAP_STATS_VAR(pmap_ncache_enter_c);
+PMAP_STATS_VAR(pmap_ncache_enter_oc);
+PMAP_STATS_VAR(pmap_ncache_enter_cc);
+PMAP_STATS_VAR(pmap_ncache_enter_coc);
+PMAP_STATS_VAR(pmap_ncache_enter_nc);
+PMAP_STATS_VAR(pmap_ncache_enter_cnc);
+PMAP_STATS_VAR(pmap_ncache_remove);
+PMAP_STATS_VAR(pmap_ncache_remove_c);
+PMAP_STATS_VAR(pmap_ncache_remove_oc);
+PMAP_STATS_VAR(pmap_ncache_remove_cc);
+PMAP_STATS_VAR(pmap_ncache_remove_coc);
+PMAP_STATS_VAR(pmap_ncache_remove_nc);
+PMAP_STATS_VAR(pmap_nzero_page);
+PMAP_STATS_VAR(pmap_nzero_page_c);
+PMAP_STATS_VAR(pmap_nzero_page_oc);
+PMAP_STATS_VAR(pmap_nzero_page_nc);
+PMAP_STATS_VAR(pmap_nzero_page_area);
+PMAP_STATS_VAR(pmap_nzero_page_area_c);
+PMAP_STATS_VAR(pmap_nzero_page_area_oc);
+PMAP_STATS_VAR(pmap_nzero_page_area_nc);
+PMAP_STATS_VAR(pmap_nzero_page_idle);
+PMAP_STATS_VAR(pmap_nzero_page_idle_c);
+PMAP_STATS_VAR(pmap_nzero_page_idle_oc);
+PMAP_STATS_VAR(pmap_nzero_page_idle_nc);
+PMAP_STATS_VAR(pmap_ncopy_page);
+PMAP_STATS_VAR(pmap_ncopy_page_c);
+PMAP_STATS_VAR(pmap_ncopy_page_oc);
+PMAP_STATS_VAR(pmap_ncopy_page_nc);
+PMAP_STATS_VAR(pmap_ncopy_page_dc);
+PMAP_STATS_VAR(pmap_ncopy_page_doc);
+PMAP_STATS_VAR(pmap_ncopy_page_sc);
+PMAP_STATS_VAR(pmap_ncopy_page_soc);
+
+PMAP_STATS_VAR(pmap_nnew_thread);
+PMAP_STATS_VAR(pmap_nnew_thread_oc);
+
+static inline u_long dtlb_get_data(u_int tlb, u_int slot);
+
+/*
+ * Quick sort callout for comparing memory regions
+ */
+static int mr_cmp(const void *a, const void *b);
+static int om_cmp(const void *a, const void *b);
+
+static int
+mr_cmp(const void *a, const void *b)
+{
+	const struct ofw_mem_region *mra;
+	const struct ofw_mem_region *mrb;
+
+	mra = a;
+	mrb = b;
+	if (mra->mr_start < mrb->mr_start)
+		return (-1);
+	else if (mra->mr_start > mrb->mr_start)
+		return (1);
+	else
+		return (0);
+}
+
+static int
+om_cmp(const void *a, const void *b)
+{
+	const struct ofw_map *oma;
+	const struct ofw_map *omb;
+
+	oma = a;
+	omb = b;
+	if (oma->om_start < omb->om_start)
+		return (-1);
+	else if (oma->om_start > omb->om_start)
+		return (1);
+	else
+		return (0);
+}
+
+static inline u_long
+dtlb_get_data(u_int tlb, u_int slot)
+{
+	u_long data;
+	register_t s;
+
+	slot = TLB_DAR_SLOT(tlb, slot);
+	/*
+	 * We read ASI_DTLB_DATA_ACCESS_REG twice back-to-back in order to
+	 * work around errata of USIII and beyond.
+	 */
+	s = intr_disable();
+	(void)ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+	data = ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+	intr_restore(s);
+	return (data);
+}
+
+/*
+ * Bootstrap the system enough to run with virtual memory.
+ */
+void
+pmap_bootstrap(u_int cpu_impl)
+{
+	struct pmap *pm;
+	struct tte *tp;
+	vm_offset_t off;
+	vm_offset_t va;
+	vm_paddr_t pa;
+	vm_size_t physsz;
+	vm_size_t virtsz;
+	u_long data;
+	u_long vpn;
+	phandle_t pmem;
+	phandle_t vmem;
+	u_int dtlb_slots_avail;
+	int i;
+	int j;
+	int sz;
+	uint32_t asi;
+	uint32_t colors;
+	uint32_t ldd;
+
+	/*
+	 * Set the kernel context.
+	 */
+	pmap_set_kctx();
+
+	colors = dcache_color_ignore != 0 ? 1 : DCACHE_COLORS;
+
+	/*
+	 * Find out what physical memory is available from the PROM and
+	 * initialize the phys_avail array.  This must be done before
+	 * pmap_bootstrap_alloc is called.
+	 */
+	if ((pmem = OF_finddevice("/memory")) == -1)
+		OF_panic("%s: finddevice /memory", __func__);
+	if ((sz = OF_getproplen(pmem, "available")) == -1)
+		OF_panic("%s: getproplen /memory/available", __func__);
+	if (sizeof(phys_avail) < sz)
+		OF_panic("%s: phys_avail too small", __func__);
+	if (sizeof(mra) < sz)
+		OF_panic("%s: mra too small", __func__);
+	bzero(mra, sz);
+	if (OF_getprop(pmem, "available", mra, sz) == -1)
+		OF_panic("%s: getprop /memory/available", __func__);
+	sz /= sizeof(*mra);
+#ifdef DIAGNOSTIC
+	OF_printf("pmap_bootstrap: physical memory\n");
+#endif
+	qsort(mra, sz, sizeof (*mra), mr_cmp);
+	physsz = 0;
+	getenv_quad("hw.physmem", &physmem);
+	physmem = btoc(physmem);
+	for (i = 0, j = 0; i < sz; i++, j += 2) {
+#ifdef DIAGNOSTIC
+		OF_printf("start=%#lx size=%#lx\n", mra[i].mr_start,
+		    mra[i].mr_size);
+#endif
+		if (physmem != 0 && btoc(physsz + mra[i].mr_size) >= physmem) {
+			if (btoc(physsz) < physmem) {
+				phys_avail[j] = mra[i].mr_start;
+				phys_avail[j + 1] = mra[i].mr_start +
+				    (ctob(physmem) - physsz);
+				physsz = ctob(physmem);
+			}
+			break;
+		}
+		phys_avail[j] = mra[i].mr_start;
+		phys_avail[j + 1] = mra[i].mr_start + mra[i].mr_size;
+		physsz += mra[i].mr_size;
+	}
+	physmem = btoc(physsz);
+
+	/*
+	 * Calculate the size of kernel virtual memory, and the size and mask
+	 * for the kernel TSB based on the phsyical memory size but limited
+	 * by the amount of dTLB slots available for locked entries if we have
+	 * to lock the TSB in the TLB (given that for spitfire-class CPUs all
+	 * of the dt64 slots can hold locked entries but there is no large
+	 * dTLB for unlocked ones, we don't use more than half of it for the
+	 * TSB).
+	 * Note that for reasons unknown OpenSolaris doesn't take advantage of
+	 * ASI_ATOMIC_QUAD_LDD_PHYS on UltraSPARC-III.  However, given that no
+	 * public documentation is available for these, the latter just might
+	 * not support it, yet.
+	 */
+	if (cpu_impl == CPU_IMPL_SPARC64V ||
+	    cpu_impl >= CPU_IMPL_ULTRASPARCIIIp) {
+		tsb_kernel_ldd_phys = 1;
+		virtsz = roundup(5 / 3 * physsz, PAGE_SIZE_4M <<
+		    (PAGE_SHIFT - TTE_SHIFT));
+	} else {
+		dtlb_slots_avail = 0;
+		for (i = 0; i < dtlb_slots; i++) {
+			data = dtlb_get_data(cpu_impl ==
+			    CPU_IMPL_ULTRASPARCIII ? TLB_DAR_T16 :
+			    TLB_DAR_T32, i);
+			if ((data & (TD_V | TD_L)) != (TD_V | TD_L))
+				dtlb_slots_avail++;
+		}
+#ifdef SMP
+		dtlb_slots_avail -= PCPU_PAGES;
+#endif
+		if (cpu_impl >= CPU_IMPL_ULTRASPARCI &&
+		    cpu_impl < CPU_IMPL_ULTRASPARCIII)
+			dtlb_slots_avail /= 2;
+		virtsz = roundup(physsz, PAGE_SIZE_4M <<
+		    (PAGE_SHIFT - TTE_SHIFT));
+		virtsz = MIN(virtsz, (dtlb_slots_avail * PAGE_SIZE_4M) <<
+		    (PAGE_SHIFT - TTE_SHIFT));
+	}
+	vm_max_kernel_address = VM_MIN_KERNEL_ADDRESS + virtsz;
+	tsb_kernel_size = virtsz >> (PAGE_SHIFT - TTE_SHIFT);
+	tsb_kernel_mask = (tsb_kernel_size >> TTE_SHIFT) - 1;
+
+	/*
+	 * Allocate the kernel TSB and lock it in the TLB if necessary.
+	 */
+	pa = pmap_bootstrap_alloc(tsb_kernel_size, colors);
+	if (pa & PAGE_MASK_4M)
+		OF_panic("%s: TSB unaligned", __func__);
+	tsb_kernel_phys = pa;
+	if (tsb_kernel_ldd_phys == 0) {
+		tsb_kernel =
+		    (struct tte *)(VM_MIN_KERNEL_ADDRESS - tsb_kernel_size);
+		pmap_map_tsb();
+		bzero(tsb_kernel, tsb_kernel_size);
+	} else {
+		tsb_kernel =
+		    (struct tte *)TLB_PHYS_TO_DIRECT(tsb_kernel_phys);
+		aszero(ASI_PHYS_USE_EC, tsb_kernel_phys, tsb_kernel_size);
+	}
+
+	/*
+	 * Allocate and map the dynamic per-CPU area for the BSP.
+	 */
+	pa = pmap_bootstrap_alloc(DPCPU_SIZE, colors);
+	dpcpu0 = (void *)TLB_PHYS_TO_DIRECT(pa);
+
+	/*
+	 * Allocate and map the message buffer.
+	 */
+	pa = pmap_bootstrap_alloc(msgbufsize, colors);
+	msgbufp = (struct msgbuf *)TLB_PHYS_TO_DIRECT(pa);
+
+	/*
+	 * Patch the TSB addresses and mask as well as the ASIs used to load
+	 * it into the trap table.
+	 */
+
+#define	LDDA_R_I_R(rd, imm_asi, rs1, rs2)				\
+	(EIF_OP(IOP_LDST) | EIF_F3_RD(rd) | EIF_F3_OP3(INS3_LDDA) |	\
+	    EIF_F3_RS1(rs1) | EIF_F3_I(0) | EIF_F3_IMM_ASI(imm_asi) |	\
+	    EIF_F3_RS2(rs2))
+#define	OR_R_I_R(rd, imm13, rs1)					\
+	(EIF_OP(IOP_MISC) | EIF_F3_RD(rd) | EIF_F3_OP3(INS2_OR) |	\
+	    EIF_F3_RS1(rs1) | EIF_F3_I(1) | EIF_IMM(imm13, 13))
+#define	SETHI(rd, imm22)						\
+	(EIF_OP(IOP_FORM2) | EIF_F2_RD(rd) | EIF_F2_OP2(INS0_SETHI) |	\
+	    EIF_IMM((imm22) >> 10, 22))
+#define	WR_R_I(rd, imm13, rs1)						\
+	(EIF_OP(IOP_MISC) | EIF_F3_RD(rd) | EIF_F3_OP3(INS2_WR) |	\
+	    EIF_F3_RS1(rs1) | EIF_F3_I(1) | EIF_IMM(imm13, 13))
+
+#define	PATCH_ASI(addr, asi) do {					\
+	if (addr[0] != WR_R_I(IF_F3_RD(addr[0]), 0x0,			\
+	    IF_F3_RS1(addr[0])))					\
+		OF_panic("%s: patched instructions have changed",	\
+		    __func__);						\
+	addr[0] |= EIF_IMM((asi), 13);					\
+	flush(addr);							\
+} while (0)
+
+#define	PATCH_LDD(addr, asi) do {					\
+	if (addr[0] != LDDA_R_I_R(IF_F3_RD(addr[0]), 0x0,		\
+	    IF_F3_RS1(addr[0]), IF_F3_RS2(addr[0])))			\
+		OF_panic("%s: patched instructions have changed",	\
+		    __func__);						\
+	addr[0] |= EIF_F3_IMM_ASI(asi);					\
+	flush(addr);							\
+} while (0)
+
+#define	PATCH_TSB(addr, val) do {					\
+	if (addr[0] != SETHI(IF_F2_RD(addr[0]), 0x0) ||			\
+	    addr[1] != OR_R_I_R(IF_F3_RD(addr[1]), 0x0,			\
+	    IF_F3_RS1(addr[1]))	||					\
+	    addr[3] != SETHI(IF_F2_RD(addr[3]), 0x0))			\
+		OF_panic("%s: patched instructions have changed",	\
+		    __func__);						\
+	addr[0] |= EIF_IMM((val) >> 42, 22);				\
+	addr[1] |= EIF_IMM((val) >> 32, 10);				\
+	addr[3] |= EIF_IMM((val) >> 10, 22);				\
+	flush(addr);							\
+	flush(addr + 1);						\
+	flush(addr + 3);						\
+} while (0)
+
+#define	PATCH_TSB_MASK(addr, val) do {					\
+	if (addr[0] != SETHI(IF_F2_RD(addr[0]), 0x0) ||			\
+	    addr[1] != OR_R_I_R(IF_F3_RD(addr[1]), 0x0,			\
+	    IF_F3_RS1(addr[1])))					\
+		OF_panic("%s: patched instructions have changed",	\
+		    __func__);						\
+	addr[0] |= EIF_IMM((val) >> 10, 22);				\
+	addr[1] |= EIF_IMM((val), 10);					\
+	flush(addr);							\
+	flush(addr + 1);						\
+} while (0)
+
+	if (tsb_kernel_ldd_phys == 0) {
+		asi = ASI_N;
+		ldd = ASI_NUCLEUS_QUAD_LDD;
+		off = (vm_offset_t)tsb_kernel;
+	} else {
+		asi = ASI_PHYS_USE_EC;
+		ldd = ASI_ATOMIC_QUAD_LDD_PHYS;
+		off = (vm_offset_t)tsb_kernel_phys;
+	}
+	PATCH_TSB(tl1_dmmu_miss_direct_patch_tsb_phys_1, tsb_kernel_phys);
+	PATCH_TSB(tl1_dmmu_miss_direct_patch_tsb_phys_end_1,
+	    tsb_kernel_phys + tsb_kernel_size - 1);
+	PATCH_ASI(tl1_dmmu_miss_patch_asi_1, asi);
+	PATCH_LDD(tl1_dmmu_miss_patch_quad_ldd_1, ldd);
+	PATCH_TSB(tl1_dmmu_miss_patch_tsb_1, off);
+	PATCH_TSB(tl1_dmmu_miss_patch_tsb_2, off);
+	PATCH_TSB_MASK(tl1_dmmu_miss_patch_tsb_mask_1, tsb_kernel_mask);
+	PATCH_TSB_MASK(tl1_dmmu_miss_patch_tsb_mask_2, tsb_kernel_mask);
+	PATCH_ASI(tl1_dmmu_prot_patch_asi_1, asi);
+	PATCH_LDD(tl1_dmmu_prot_patch_quad_ldd_1, ldd);
+	PATCH_TSB(tl1_dmmu_prot_patch_tsb_1, off);
+	PATCH_TSB(tl1_dmmu_prot_patch_tsb_2, off);
+	PATCH_TSB_MASK(tl1_dmmu_prot_patch_tsb_mask_1, tsb_kernel_mask);
+	PATCH_TSB_MASK(tl1_dmmu_prot_patch_tsb_mask_2, tsb_kernel_mask);
+	PATCH_ASI(tl1_immu_miss_patch_asi_1, asi);
+	PATCH_LDD(tl1_immu_miss_patch_quad_ldd_1, ldd);
+	PATCH_TSB(tl1_immu_miss_patch_tsb_1, off);
+	PATCH_TSB(tl1_immu_miss_patch_tsb_2, off);
+	PATCH_TSB_MASK(tl1_immu_miss_patch_tsb_mask_1, tsb_kernel_mask);
+	PATCH_TSB_MASK(tl1_immu_miss_patch_tsb_mask_2, tsb_kernel_mask);
+
+	/*
+	 * Enter fake 8k pages for the 4MB kernel pages, so that
+	 * pmap_kextract() will work for them.
+	 */
+	for (i = 0; i < kernel_tlb_slots; i++) {
+		pa = kernel_tlbs[i].te_pa;
+		va = kernel_tlbs[i].te_va;
+		for (off = 0; off < PAGE_SIZE_4M; off += PAGE_SIZE) {
+			tp = tsb_kvtotte(va + off);
+			vpn = TV_VPN(va + off, TS_8K);
+			data = TD_V | TD_8K | TD_PA(pa + off) | TD_REF |
+			    TD_SW | TD_CP | TD_CV | TD_P | TD_W;
+			pmap_bootstrap_set_tte(tp, vpn, data);
+		}
+	}
+
+	/*
+	 * Set the start and end of KVA.  The kernel is loaded starting
+	 * at the first available 4MB super page, so we advance to the
+	 * end of the last one used for it.
+	 */
+	virtual_avail = KERNBASE + kernel_tlb_slots * PAGE_SIZE_4M;
+	virtual_end = vm_max_kernel_address;
+	kernel_vm_end = vm_max_kernel_address;
+
+	/*
+	 * Allocate kva space for temporary mappings.
+	 */
+	pmap_idle_map = virtual_avail;
+	virtual_avail += PAGE_SIZE * colors;
+	pmap_temp_map_1 = virtual_avail;
+	virtual_avail += PAGE_SIZE * colors;
+	pmap_temp_map_2 = virtual_avail;
+	virtual_avail += PAGE_SIZE * colors;
+
+	/*
+	 * Allocate a kernel stack with guard page for thread0 and map it
+	 * into the kernel TSB.  We must ensure that the virtual address is
+	 * colored properly for corresponding CPUs, since we're allocating
+	 * from phys_avail so the memory won't have an associated vm_page_t.
+	 */
+	pa = pmap_bootstrap_alloc(KSTACK_PAGES * PAGE_SIZE, colors);
+	kstack0_phys = pa;
+	virtual_avail += roundup(KSTACK_GUARD_PAGES, colors) * PAGE_SIZE;
+	kstack0 = virtual_avail;
+	virtual_avail += roundup(KSTACK_PAGES, colors) * PAGE_SIZE;
+	if (dcache_color_ignore == 0)
+		KASSERT(DCACHE_COLOR(kstack0) == DCACHE_COLOR(kstack0_phys),
+		    ("pmap_bootstrap: kstack0 miscolored"));
+	for (i = 0; i < KSTACK_PAGES; i++) {
+		pa = kstack0_phys + i * PAGE_SIZE;
+		va = kstack0 + i * PAGE_SIZE;
+		tp = tsb_kvtotte(va);
+		vpn = TV_VPN(va, TS_8K);
+		data = TD_V | TD_8K | TD_PA(pa) | TD_REF | TD_SW | TD_CP |
+		    TD_CV | TD_P | TD_W;
+		pmap_bootstrap_set_tte(tp, vpn, data);
+	}
+
+	/*
+	 * Calculate the last available physical address.
+	 */
+	for (i = 0; phys_avail[i + 2] != 0; i += 2)
+		;
+	Maxmem = sparc64_btop(phys_avail[i + 1]);
+
+	/*
+	 * Add the PROM mappings to the kernel TSB.
+	 */
+	if ((vmem = OF_finddevice("/virtual-memory")) == -1)
+		OF_panic("%s: finddevice /virtual-memory", __func__);
+	if ((sz = OF_getproplen(vmem, "translations")) == -1)
+		OF_panic("%s: getproplen translations", __func__);
+	if (sizeof(translations) < sz)
+		OF_panic("%s: translations too small", __func__);
+	bzero(translations, sz);
+	if (OF_getprop(vmem, "translations", translations, sz) == -1)
+		OF_panic("%s: getprop /virtual-memory/translations",
+		    __func__);
+	sz /= sizeof(*translations);
+	translations_size = sz;
+#ifdef DIAGNOSTIC
+	OF_printf("pmap_bootstrap: translations\n");
+#endif
+	qsort(translations, sz, sizeof (*translations), om_cmp);
+	for (i = 0; i < sz; i++) {
+#ifdef DIAGNOSTIC
+		OF_printf("translation: start=%#lx size=%#lx tte=%#lx\n",
+		    translations[i].om_start, translations[i].om_size,
+		    translations[i].om_tte);
+#endif
+		if ((translations[i].om_tte & TD_V) == 0)
+			continue;
+		if (translations[i].om_start < VM_MIN_PROM_ADDRESS ||
+		    translations[i].om_start > VM_MAX_PROM_ADDRESS)
+			continue;
+		for (off = 0; off < translations[i].om_size;
+		    off += PAGE_SIZE) {
+			va = translations[i].om_start + off;
+			tp = tsb_kvtotte(va);
+			vpn = TV_VPN(va, TS_8K);
+			data = ((translations[i].om_tte &
+			    ~((TD_SOFT2_MASK << TD_SOFT2_SHIFT) |
+			    (cpu_impl >= CPU_IMPL_ULTRASPARCI &&
+			    cpu_impl < CPU_IMPL_ULTRASPARCIII ?
+			    (TD_DIAG_SF_MASK << TD_DIAG_SF_SHIFT) :
+			    (TD_RSVD_CH_MASK << TD_RSVD_CH_SHIFT)) |
+			    (TD_SOFT_MASK << TD_SOFT_SHIFT))) | TD_EXEC) +
+			    off;
+			pmap_bootstrap_set_tte(tp, vpn, data);
+		}
+	}
+
+	/*
+	 * Get the available physical memory ranges from /memory/reg.  These
+	 * are only used for kernel dumps, but it may not be wise to do PROM
+	 * calls in that situation.
+	 */
+	if ((sz = OF_getproplen(pmem, "reg")) == -1)
+		OF_panic("%s: getproplen /memory/reg", __func__);
+	if (sizeof(sparc64_memreg) < sz)
+		OF_panic("%s: sparc64_memreg too small", __func__);
+	if (OF_getprop(pmem, "reg", sparc64_memreg, sz) == -1)
+		OF_panic("%s: getprop /memory/reg", __func__);
+	sparc64_nmemreg = sz / sizeof(*sparc64_memreg);
+
+	/*
+	 * Initialize the kernel pmap (which is statically allocated).
+	 */
+	pm = kernel_pmap;
+	PMAP_LOCK_INIT(pm);
+	for (i = 0; i < MAXCPU; i++)
+		pm->pm_context[i] = TLB_CTX_KERNEL;
+	CPU_FILL(&pm->pm_active);
+
+	/*
+	 * Initialize the global tte list lock, which is more commonly
+	 * known as the pmap pv global lock.
+	 */
+	rw_init(&tte_list_global_lock, "pmap pv global");
+
+	/*
+	 * Flush all non-locked TLB entries possibly left over by the
+	 * firmware.
+	 */
+	tlb_flush_nonlocked();
+}
+
+/*
+ * Map the 4MB kernel TSB pages.
+ */
+void
+pmap_map_tsb(void)
+{
+	vm_offset_t va;
+	vm_paddr_t pa;
+	u_long data;
+	int i;
+
+	for (i = 0; i < tsb_kernel_size; i += PAGE_SIZE_4M) {
+		va = (vm_offset_t)tsb_kernel + i;
+		pa = tsb_kernel_phys + i;
+		data = TD_V | TD_4M | TD_PA(pa) | TD_L | TD_CP | TD_CV |
+		    TD_P | TD_W;
+		stxa(AA_DMMU_TAR, ASI_DMMU, TLB_TAR_VA(va) |
+		    TLB_TAR_CTX(TLB_CTX_KERNEL));
+		stxa_sync(0, ASI_DTLB_DATA_IN_REG, data);
+	}
+}
+
+/*
+ * Set the secondary context to be the kernel context (needed for FP block
+ * operations in the kernel).
+ */
+void
+pmap_set_kctx(void)
+{
+
+	stxa(AA_DMMU_SCXR, ASI_DMMU, (ldxa(AA_DMMU_SCXR, ASI_DMMU) &
+	    TLB_CXR_PGSZ_MASK) | TLB_CTX_KERNEL);
+	flush(KERNBASE);
+}
+
+/*
+ * Allocate a physical page of memory directly from the phys_avail map.
+ * Can only be called from pmap_bootstrap before avail start and end are
+ * calculated.
+ */
+static vm_paddr_t
+pmap_bootstrap_alloc(vm_size_t size, uint32_t colors)
+{
+	vm_paddr_t pa;
+	int i;
+
+	size = roundup(size, PAGE_SIZE * colors);
+	for (i = 0; phys_avail[i + 1] != 0; i += 2) {
+		if (phys_avail[i + 1] - phys_avail[i] < size)
+			continue;
+		pa = phys_avail[i];
+		phys_avail[i] += size;
+		return (pa);
+	}
+	OF_panic("%s: no suitable region found", __func__);
+}
+
+/*
+ * Set a TTE.  This function is intended as a helper when tsb_kernel is
+ * direct-mapped but we haven't taken over the trap table, yet, as it's the
+ * case when we are taking advantage of ASI_ATOMIC_QUAD_LDD_PHYS to access
+ * the kernel TSB.
+ */
+void
+pmap_bootstrap_set_tte(struct tte *tp, u_long vpn, u_long data)
+{
+
+	if (tsb_kernel_ldd_phys == 0) {
+		tp->tte_vpn = vpn;
+		tp->tte_data = data;
+	} else {
+		stxa((vm_paddr_t)tp + offsetof(struct tte, tte_vpn),
+		    ASI_PHYS_USE_EC, vpn);
+		stxa((vm_paddr_t)tp + offsetof(struct tte, tte_data),
+		    ASI_PHYS_USE_EC, data);
+	}
+}
+
+/*
+ * Initialize a vm_page's machine-dependent fields.
+ */
+void
+pmap_page_init(vm_page_t m)
+{
+
+	TAILQ_INIT(&m->md.tte_list);
+	m->md.color = DCACHE_COLOR(VM_PAGE_TO_PHYS(m));
+	m->md.pmap = NULL;
+}
+
+/*
+ * Initialize the pmap module.
+ */
+void
+pmap_init(void)
+{
+	vm_offset_t addr;
+	vm_size_t size;
+	int result;
+	int i;
+
+	for (i = 0; i < translations_size; i++) {
+		addr = translations[i].om_start;
+		size = translations[i].om_size;
+		if ((translations[i].om_tte & TD_V) == 0)
+			continue;
+		if (addr < VM_MIN_PROM_ADDRESS || addr > VM_MAX_PROM_ADDRESS)
+			continue;
+		result = vm_map_find(kernel_map, NULL, 0, &addr, size, 0,
+		    VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT);
+		if (result != KERN_SUCCESS || addr != translations[i].om_start)
+			panic("pmap_init: vm_map_find");
+	}
+}
+
+/*
+ * Extract the physical page address associated with the given
+ * map/virtual_address pair.
+ */
+vm_paddr_t
+pmap_extract(pmap_t pm, vm_offset_t va)
+{
+	struct tte *tp;
+	vm_paddr_t pa;
+
+	if (pm == kernel_pmap)
+		return (pmap_kextract(va));
+	PMAP_LOCK(pm);
+	tp = tsb_tte_lookup(pm, va);
+	if (tp == NULL)
+		pa = 0;
+	else
+		pa = TTE_GET_PA(tp) | (va & TTE_GET_PAGE_MASK(tp));
+	PMAP_UNLOCK(pm);
+	return (pa);
+}
+
+/*
+ * Atomically extract and hold the physical page with the given
+ * pmap and virtual address pair if that mapping permits the given
+ * protection.
+ */
+vm_page_t
+pmap_extract_and_hold(pmap_t pm, vm_offset_t va, vm_prot_t prot)
+{
+	struct tte *tp;
+	vm_page_t m;
+	vm_paddr_t pa;
+
+	m = NULL;
+	pa = 0;
+	PMAP_LOCK(pm);
+retry:
+	if (pm == kernel_pmap) {
+		if (va >= VM_MIN_DIRECT_ADDRESS) {
+			tp = NULL;
+			m = PHYS_TO_VM_PAGE(TLB_DIRECT_TO_PHYS(va));
+			(void)vm_page_pa_tryrelock(pm, TLB_DIRECT_TO_PHYS(va),
+			    &pa);
+			vm_page_hold(m);
+		} else {
+			tp = tsb_kvtotte(va);
+			if ((tp->tte_data & TD_V) == 0)
+				tp = NULL;
+		}
+	} else
+		tp = tsb_tte_lookup(pm, va);
+	if (tp != NULL && ((tp->tte_data & TD_SW) ||
+	    (prot & VM_PROT_WRITE) == 0)) {
+		if (vm_page_pa_tryrelock(pm, TTE_GET_PA(tp), &pa))
+			goto retry;
+		m = PHYS_TO_VM_PAGE(TTE_GET_PA(tp));
+		vm_page_hold(m);
+	}
+	PA_UNLOCK_COND(pa);
+	PMAP_UNLOCK(pm);
+	return (m);
+}
+
+/*
+ * Extract the physical page address associated with the given kernel virtual
+ * address.
+ */
+vm_paddr_t
+pmap_kextract(vm_offset_t va)
+{
+	struct tte *tp;
+
+	if (va >= VM_MIN_DIRECT_ADDRESS)
+		return (TLB_DIRECT_TO_PHYS(va));
+	tp = tsb_kvtotte(va);
+	if ((tp->tte_data & TD_V) == 0)
+		return (0);
+	return (TTE_GET_PA(tp) | (va & TTE_GET_PAGE_MASK(tp)));
+}
+
+int
+pmap_cache_enter(vm_page_t m, vm_offset_t va)
+{
+	struct tte *tp;
+	int color;
+
+	rw_assert(&tte_list_global_lock, RA_WLOCKED);
+	KASSERT((m->flags & PG_FICTITIOUS) == 0,
+	    ("pmap_cache_enter: fake page"));
+	PMAP_STATS_INC(pmap_ncache_enter);
+
+	if (dcache_color_ignore != 0)
+		return (1);
+
+	/*
+	 * Find the color for this virtual address and note the added mapping.
+	 */
+	color = DCACHE_COLOR(va);
+	m->md.colors[color]++;
+
+	/*
+	 * If all existing mappings have the same color, the mapping is
+	 * cacheable.
+	 */
+	if (m->md.color == color) {
+		KASSERT(m->md.colors[DCACHE_OTHER_COLOR(color)] == 0,
+		    ("pmap_cache_enter: cacheable, mappings of other color"));
+		if (m->md.color == DCACHE_COLOR(VM_PAGE_TO_PHYS(m)))
+			PMAP_STATS_INC(pmap_ncache_enter_c);
+		else
+			PMAP_STATS_INC(pmap_ncache_enter_oc);
+		return (1);
+	}
+
+	/*
+	 * If there are no mappings of the other color, and the page still has
+	 * the wrong color, this must be a new mapping.  Change the color to
+	 * match the new mapping, which is cacheable.  We must flush the page
+	 * from the cache now.
+	 */
+	if (m->md.colors[DCACHE_OTHER_COLOR(color)] == 0) {
+		KASSERT(m->md.colors[color] == 1,
+		    ("pmap_cache_enter: changing color, not new mapping"));
+		dcache_page_inval(VM_PAGE_TO_PHYS(m));
+		m->md.color = color;
+		if (m->md.color == DCACHE_COLOR(VM_PAGE_TO_PHYS(m)))
+			PMAP_STATS_INC(pmap_ncache_enter_cc);
+		else
+			PMAP_STATS_INC(pmap_ncache_enter_coc);
+		return (1);
+	}
+
+	/*
+	 * If the mapping is already non-cacheable, just return.
+	 */
+	if (m->md.color == -1) {
+		PMAP_STATS_INC(pmap_ncache_enter_nc);
+		return (0);
+	}
+
+	PMAP_STATS_INC(pmap_ncache_enter_cnc);
+
+	/*
+	 * Mark all mappings as uncacheable, flush any lines with the other
+	 * color out of the dcache, and set the color to none (-1).
+	 */
+	TAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
+		atomic_clear_long(&tp->tte_data, TD_CV);
+		tlb_page_demap(TTE_GET_PMAP(tp), TTE_GET_VA(tp));
+	}
+	dcache_page_inval(VM_PAGE_TO_PHYS(m));
+	m->md.color = -1;
+	return (0);
+}
+
+static void
+pmap_cache_remove(vm_page_t m, vm_offset_t va)
+{
+	struct tte *tp;
+	int color;
+
+	rw_assert(&tte_list_global_lock, RA_WLOCKED);
+	CTR3(KTR_PMAP, "pmap_cache_remove: m=%p va=%#lx c=%d", m, va,
+	    m->md.colors[DCACHE_COLOR(va)]);
+	KASSERT((m->flags & PG_FICTITIOUS) == 0,
+	    ("pmap_cache_remove: fake page"));
+	PMAP_STATS_INC(pmap_ncache_remove);
+
+	if (dcache_color_ignore != 0)
+		return;
+
+	KASSERT(m->md.colors[DCACHE_COLOR(va)] > 0,
+	    ("pmap_cache_remove: no mappings %d <= 0",
+	    m->md.colors[DCACHE_COLOR(va)]));
+
+	/*
+	 * Find the color for this virtual address and note the removal of
+	 * the mapping.
+	 */
+	color = DCACHE_COLOR(va);
+	m->md.colors[color]--;
+
+	/*
+	 * If the page is cacheable, just return and keep the same color, even
+	 * if there are no longer any mappings.
+	 */
+	if (m->md.color != -1) {
+		if (m->md.color == DCACHE_COLOR(VM_PAGE_TO_PHYS(m)))
+			PMAP_STATS_INC(pmap_ncache_remove_c);
+		else
+			PMAP_STATS_INC(pmap_ncache_remove_oc);
+		return;
+	}
+
+	KASSERT(m->md.colors[DCACHE_OTHER_COLOR(color)] != 0,
+	    ("pmap_cache_remove: uncacheable, no mappings of other color"));
+
+	/*
+	 * If the page is not cacheable (color is -1), and the number of
+	 * mappings for this color is not zero, just return.  There are
+	 * mappings of the other color still, so remain non-cacheable.
+	 */
+	if (m->md.colors[color] != 0) {
+		PMAP_STATS_INC(pmap_ncache_remove_nc);
+		return;
+	}
+
+	/*
+	 * The number of mappings for this color is now zero.  Recache the
+	 * other colored mappings, and change the page color to the other
+	 * color.  There should be no lines in the data cache for this page,
+	 * so flushing should not be needed.
+	 */
+	TAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
+		atomic_set_long(&tp->tte_data, TD_CV);
+		tlb_page_demap(TTE_GET_PMAP(tp), TTE_GET_VA(tp));
+	}
+	m->md.color = DCACHE_OTHER_COLOR(color);
+
+	if (m->md.color == DCACHE_COLOR(VM_PAGE_TO_PHYS(m)))
+		PMAP_STATS_INC(pmap_ncache_remove_cc);
+	else
+		PMAP_STATS_INC(pmap_ncache_remove_coc);
+}
+
+/*
+ * Map a wired page into kernel virtual address space.
+ */
+void
+pmap_kenter(vm_offset_t va, vm_page_t m)
+{
+	vm_offset_t ova;
+	struct tte *tp;
+	vm_page_t om;
+	u_long data;
+
+	rw_assert(&tte_list_global_lock, RA_WLOCKED);
+	PMAP_STATS_INC(pmap_nkenter);
+	tp = tsb_kvtotte(va);
+	CTR4(KTR_PMAP, "pmap_kenter: va=%#lx pa=%#lx tp=%p data=%#lx",
+	    va, VM_PAGE_TO_PHYS(m), tp, tp->tte_data);
+	if (DCACHE_COLOR(VM_PAGE_TO_PHYS(m)) != DCACHE_COLOR(va)) {
+		CTR5(KTR_SPARE2,
+	"pmap_kenter: off color va=%#lx pa=%#lx o=%p ot=%d pi=%#lx",
+		    va, VM_PAGE_TO_PHYS(m), m->object,
+		    m->object ? m->object->type : -1,
+		    m->pindex);
+		PMAP_STATS_INC(pmap_nkenter_oc);
+	}
+	if ((tp->tte_data & TD_V) != 0) {
+		om = PHYS_TO_VM_PAGE(TTE_GET_PA(tp));
+		ova = TTE_GET_VA(tp);
+		if (m == om && va == ova) {
+			PMAP_STATS_INC(pmap_nkenter_stupid);
+			return;
+		}
+		TAILQ_REMOVE(&om->md.tte_list, tp, tte_link);
+		pmap_cache_remove(om, ova);
+		if (va != ova)
+			tlb_page_demap(kernel_pmap, ova);
+	}
+	data = TD_V | TD_8K | VM_PAGE_TO_PHYS(m) | TD_REF | TD_SW | TD_CP |
+	    TD_P | TD_W;
+	if (pmap_cache_enter(m, va) != 0)
+		data |= TD_CV;
+	tp->tte_vpn = TV_VPN(va, TS_8K);
+	tp->tte_data = data;
+	TAILQ_INSERT_TAIL(&m->md.tte_list, tp, tte_link);
+}
+
+/*
+ * Map a wired page into kernel virtual address space.  This additionally
+ * takes a flag argument which is or'ed to the TTE data.  This is used by
+ * sparc64_bus_mem_map().
+ * NOTE: if the mapping is non-cacheable, it's the caller's responsibility
+ * to flush entries that might still be in the cache, if applicable.
+ */
+void
+pmap_kenter_flags(vm_offset_t va, vm_paddr_t pa, u_long flags)
+{
+	struct tte *tp;
+
+	tp = tsb_kvtotte(va);
+	CTR4(KTR_PMAP, "pmap_kenter_flags: va=%#lx pa=%#lx tp=%p data=%#lx",
+	    va, pa, tp, tp->tte_data);
+	tp->tte_vpn = TV_VPN(va, TS_8K);
+	tp->tte_data = TD_V | TD_8K | TD_PA(pa) | TD_REF | TD_P | flags;
+}
+
+/*
+ * Remove a wired page from kernel virtual address space.
+ */
+void
+pmap_kremove(vm_offset_t va)
+{
+	struct tte *tp;
+	vm_page_t m;
+
+	rw_assert(&tte_list_global_lock, RA_WLOCKED);
+	PMAP_STATS_INC(pmap_nkremove);
+	tp = tsb_kvtotte(va);
+	CTR3(KTR_PMAP, "pmap_kremove: va=%#lx tp=%p data=%#lx", va, tp,
+	    tp->tte_data);
+	if ((tp->tte_data & TD_V) == 0)
+		return;
+	m = PHYS_TO_VM_PAGE(TTE_GET_PA(tp));
+	TAILQ_REMOVE(&m->md.tte_list, tp, tte_link);
+	pmap_cache_remove(m, va);
+	TTE_ZERO(tp);
+}
+
+/*
+ * Inverse of pmap_kenter_flags, used by bus_space_unmap().
+ */
+void
+pmap_kremove_flags(vm_offset_t va)
+{
+	struct tte *tp;
+
+	tp = tsb_kvtotte(va);
+	CTR3(KTR_PMAP, "pmap_kremove_flags: va=%#lx tp=%p data=%#lx", va, tp,
+	    tp->tte_data);
+	TTE_ZERO(tp);
+}
+
+/*
+ * Map a range of physical addresses into kernel virtual address space.
+ *
+ * The value passed in *virt is a suggested virtual address for the mapping.
+ * Architectures which can support a direct-mapped physical to virtual region
+ * can return the appropriate address within that region, leaving '*virt'
+ * unchanged.
+ */
+vm_offset_t
+pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
+{
+
+	return (TLB_PHYS_TO_DIRECT(start));
+}
+
+/*
+ * Map a list of wired pages into kernel virtual address space.  This is
+ * intended for temporary mappings which do not need page modification or
+ * references recorded.  Existing mappings in the region are overwritten.
+ */
+void
+pmap_qenter(vm_offset_t sva, vm_page_t *m, int count)
+{
+	vm_offset_t va;
+
+	PMAP_STATS_INC(pmap_nqenter);
+	va = sva;
+	rw_wlock(&tte_list_global_lock);
+	while (count-- > 0) {
+		pmap_kenter(va, *m);
+		va += PAGE_SIZE;
+		m++;
+	}
+	rw_wunlock(&tte_list_global_lock);
+	tlb_range_demap(kernel_pmap, sva, va);
+}
+
+/*
+ * Remove page mappings from kernel virtual address space.  Intended for
+ * temporary mappings entered by pmap_qenter.
+ */
+void
+pmap_qremove(vm_offset_t sva, int count)
+{
+	vm_offset_t va;
+
+	PMAP_STATS_INC(pmap_nqremove);
+	va = sva;
+	rw_wlock(&tte_list_global_lock);
+	while (count-- > 0) {
+		pmap_kremove(va);
+		va += PAGE_SIZE;
+	}
+	rw_wunlock(&tte_list_global_lock);
+	tlb_range_demap(kernel_pmap, sva, va);
+}
+
+/*
+ * Initialize the pmap associated with process 0.
+ */
+void
+pmap_pinit0(pmap_t pm)
+{
+	int i;
+
+	PMAP_LOCK_INIT(pm);
+	for (i = 0; i < MAXCPU; i++)
+		pm->pm_context[i] = TLB_CTX_KERNEL;
+	CPU_ZERO(&pm->pm_active);
+	pm->pm_tsb = NULL;
+	pm->pm_tsb_obj = NULL;
+	bzero(&pm->pm_stats, sizeof(pm->pm_stats));
+}
+
+/*
+ * Initialize a preallocated and zeroed pmap structure, such as one in a
+ * vmspace structure.
+ */
+int
+pmap_pinit(pmap_t pm)
+{
+	vm_page_t ma[TSB_PAGES];
+	vm_page_t m;
+	int i;
+
+	/*
+	 * Allocate KVA space for the TSB.
+	 */
+	if (pm->pm_tsb == NULL) {
+		pm->pm_tsb = (struct tte *)kva_alloc(TSB_BSIZE);
+		if (pm->pm_tsb == NULL)
+			return (0);
+		}
+
+	/*
+	 * Allocate an object for it.
+	 */
+	if (pm->pm_tsb_obj == NULL)
+		pm->pm_tsb_obj = vm_object_allocate(OBJT_PHYS, TSB_PAGES);
+
+	for (i = 0; i < MAXCPU; i++)
+		pm->pm_context[i] = -1;
+	CPU_ZERO(&pm->pm_active);
+
+	VM_OBJECT_WLOCK(pm->pm_tsb_obj);
+	for (i = 0; i < TSB_PAGES; i++) {
+		m = vm_page_grab(pm->pm_tsb_obj, i, VM_ALLOC_NOBUSY |
+		    VM_ALLOC_WIRED | VM_ALLOC_ZERO);
+		m->valid = VM_PAGE_BITS_ALL;
+		m->md.pmap = pm;
+		ma[i] = m;
+	}
+	VM_OBJECT_WUNLOCK(pm->pm_tsb_obj);
+	pmap_qenter((vm_offset_t)pm->pm_tsb, ma, TSB_PAGES);
+
+	bzero(&pm->pm_stats, sizeof(pm->pm_stats));
+	return (1);
+}
+
+/*
+ * 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 pm)
+{
+	vm_object_t obj;
+	vm_page_t m;
+#ifdef SMP
+	struct pcpu *pc;
+#endif
+
+	CTR2(KTR_PMAP, "pmap_release: ctx=%#x tsb=%p",
+	    pm->pm_context[curcpu], pm->pm_tsb);
+	KASSERT(pmap_resident_count(pm) == 0,
+	    ("pmap_release: resident pages %ld != 0",
+	    pmap_resident_count(pm)));
+
+	/*
+	 * After the pmap was freed, it might be reallocated to a new process.
+	 * When switching, this might lead us to wrongly assume that we need
+	 * not switch contexts because old and new pmap pointer are equal.
+	 * Therefore, make sure that this pmap is not referenced by any PCPU
+	 * pointer any more.  This could happen in two cases:
+	 * - A process that referenced the pmap is currently exiting on a CPU.
+	 *   However, it is guaranteed to not switch in any more after setting
+	 *   its state to PRS_ZOMBIE.
+	 * - A process that referenced this pmap ran on a CPU, but we switched
+	 *   to a kernel thread, leaving the pmap pointer unchanged.
+	 */
+#ifdef SMP
+	sched_pin();
+	STAILQ_FOREACH(pc, &cpuhead, pc_allcpu)
+		atomic_cmpset_rel_ptr((uintptr_t *)&pc->pc_pmap,
+		    (uintptr_t)pm, (uintptr_t)NULL);
+	sched_unpin();
+#else
+	critical_enter();
+	if (PCPU_GET(pmap) == pm)
+		PCPU_SET(pmap, NULL);
+	critical_exit();
+#endif
+
+	pmap_qremove((vm_offset_t)pm->pm_tsb, TSB_PAGES);
+	obj = pm->pm_tsb_obj;
+	VM_OBJECT_WLOCK(obj);
+	KASSERT(obj->ref_count == 1, ("pmap_release: tsbobj ref count != 1"));
+	while (!TAILQ_EMPTY(&obj->memq)) {
+		m = TAILQ_FIRST(&obj->memq);
+		m->md.pmap = NULL;
+		m->wire_count--;
+		atomic_subtract_int(&cnt.v_wire_count, 1);
+		vm_page_free_zero(m);
+	}
+	VM_OBJECT_WUNLOCK(obj);
+}
+
+/*
+ * Grow the number of kernel page table entries.  Unneeded.
+ */
+void
+pmap_growkernel(vm_offset_t addr)
+{
+
+	panic("pmap_growkernel: can't grow kernel");
+}
+
+int
+pmap_remove_tte(struct pmap *pm, struct pmap *pm2, struct tte *tp,
+    vm_offset_t va)
+{
+	vm_page_t m;
+	u_long data;
+
+	rw_assert(&tte_list_global_lock, RA_WLOCKED);
+	data = atomic_readandclear_long(&tp->tte_data);
+	if ((data & TD_FAKE) == 0) {
+		m = PHYS_TO_VM_PAGE(TD_PA(data));
+		TAILQ_REMOVE(&m->md.tte_list, tp, tte_link);
+		if ((data & TD_WIRED) != 0)
+			pm->pm_stats.wired_count--;
+		if ((data & TD_PV) != 0) {
+			if ((data & TD_W) != 0)
+				vm_page_dirty(m);
+			if ((data & TD_REF) != 0)
+				vm_page_aflag_set(m, PGA_REFERENCED);
+			if (TAILQ_EMPTY(&m->md.tte_list))
+				vm_page_aflag_clear(m, PGA_WRITEABLE);
+			pm->pm_stats.resident_count--;
+		}
+		pmap_cache_remove(m, va);
+	}
+	TTE_ZERO(tp);
+	if (PMAP_REMOVE_DONE(pm))
+		return (0);
+	return (1);
+}
+
+/*
+ * Remove the given range of addresses from the specified map.
+ */
+void
+pmap_remove(pmap_t pm, vm_offset_t start, vm_offset_t end)
+{
+	struct tte *tp;
+	vm_offset_t va;
+
+	CTR3(KTR_PMAP, "pmap_remove: ctx=%#lx start=%#lx end=%#lx",
+	    pm->pm_context[curcpu], start, end);
+	if (PMAP_REMOVE_DONE(pm))
+		return;
+	rw_wlock(&tte_list_global_lock);
+	PMAP_LOCK(pm);
+	if (end - start > PMAP_TSB_THRESH) {
+		tsb_foreach(pm, NULL, start, end, pmap_remove_tte);
+		tlb_context_demap(pm);
+	} else {
+		for (va = start; va < end; va += PAGE_SIZE)
+			if ((tp = tsb_tte_lookup(pm, va)) != NULL &&
+			    !pmap_remove_tte(pm, NULL, tp, va))
+				break;
+		tlb_range_demap(pm, start, end - 1);
+	}
+	PMAP_UNLOCK(pm);
+	rw_wunlock(&tte_list_global_lock);
+}
+
+void
+pmap_remove_all(vm_page_t m)
+{
+	struct pmap *pm;
+	struct tte *tpn;
+	struct tte *tp;
+	vm_offset_t va;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_remove_all: page %p is not managed", m));
+	rw_wlock(&tte_list_global_lock);
+	for (tp = TAILQ_FIRST(&m->md.tte_list); tp != NULL; tp = tpn) {
+		tpn = TAILQ_NEXT(tp, tte_link);
+		if ((tp->tte_data & TD_PV) == 0)
+			continue;
+		pm = TTE_GET_PMAP(tp);
+		va = TTE_GET_VA(tp);
+		PMAP_LOCK(pm);
+		if ((tp->tte_data & TD_WIRED) != 0)
+			pm->pm_stats.wired_count--;
+		if ((tp->tte_data & TD_REF) != 0)
+			vm_page_aflag_set(m, PGA_REFERENCED);
+		if ((tp->tte_data & TD_W) != 0)
+			vm_page_dirty(m);
+		tp->tte_data &= ~TD_V;
+		tlb_page_demap(pm, va);
+		TAILQ_REMOVE(&m->md.tte_list, tp, tte_link);
+		pm->pm_stats.resident_count--;
+		pmap_cache_remove(m, va);
+		TTE_ZERO(tp);
+		PMAP_UNLOCK(pm);
+	}
+	vm_page_aflag_clear(m, PGA_WRITEABLE);
+	rw_wunlock(&tte_list_global_lock);
+}
+
+static int
+pmap_protect_tte(struct pmap *pm, struct pmap *pm2, struct tte *tp,
+    vm_offset_t va)
+{
+	u_long data;
+	vm_page_t m;
+
+	PMAP_LOCK_ASSERT(pm, MA_OWNED);
+	data = atomic_clear_long(&tp->tte_data, TD_SW | TD_W);
+	if ((data & (TD_PV | TD_W)) == (TD_PV | TD_W)) {
+		m = PHYS_TO_VM_PAGE(TD_PA(data));
+		vm_page_dirty(m);
+	}
+	return (1);
+}
+
+/*
+ * Set the physical protection on the specified range of this map as requested.
+ */
+void
+pmap_protect(pmap_t pm, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
+{
+	vm_offset_t va;
+	struct tte *tp;
+
+	CTR4(KTR_PMAP, "pmap_protect: ctx=%#lx sva=%#lx eva=%#lx prot=%#lx",
+	    pm->pm_context[curcpu], sva, eva, prot);
+
+	if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
+		pmap_remove(pm, sva, eva);
+		return;
+	}
+
+	if (prot & VM_PROT_WRITE)
+		return;
+
+	PMAP_LOCK(pm);
+	if (eva - sva > PMAP_TSB_THRESH) {
+		tsb_foreach(pm, NULL, sva, eva, pmap_protect_tte);
+		tlb_context_demap(pm);
+	} else {
+		for (va = sva; va < eva; va += PAGE_SIZE)
+			if ((tp = tsb_tte_lookup(pm, va)) != NULL)
+				pmap_protect_tte(pm, NULL, tp, va);
+		tlb_range_demap(pm, sva, eva - 1);
+	}
+	PMAP_UNLOCK(pm);
+}
+
+/*
+ * Map the given physical page at the specified virtual address in the
+ * target pmap with the protection requested.  If specified the page
+ * will be wired down.
+ */
+int
+pmap_enter(pmap_t pm, vm_offset_t va, vm_page_t m, vm_prot_t prot,
+    u_int flags, int8_t psind)
+{
+	int rv;
+
+	rw_wlock(&tte_list_global_lock);
+	PMAP_LOCK(pm);
+	rv = pmap_enter_locked(pm, va, m, prot, flags, psind);
+	rw_wunlock(&tte_list_global_lock);
+	PMAP_UNLOCK(pm);
+	return (rv);
+}
+
+/*
+ * Map the given physical page at the specified virtual address in the
+ * target pmap with the protection requested.  If specified the page
+ * will be wired down.
+ *
+ * The page queues and pmap must be locked.
+ */
+static int
+pmap_enter_locked(pmap_t pm, vm_offset_t va, vm_page_t m, vm_prot_t prot,
+    u_int flags, int8_t psind __unused)
+{
+	struct tte *tp;
+	vm_paddr_t pa;
+	vm_page_t real;
+	u_long data;
+	boolean_t wired;
+
+	rw_assert(&tte_list_global_lock, RA_WLOCKED);
+	PMAP_LOCK_ASSERT(pm, MA_OWNED);
+	if ((m->oflags & VPO_UNMANAGED) == 0 && !vm_page_xbusied(m))
+		VM_OBJECT_ASSERT_LOCKED(m->object);
+	PMAP_STATS_INC(pmap_nenter);
+	pa = VM_PAGE_TO_PHYS(m);
+	wired = (flags & PMAP_ENTER_WIRED) != 0;
+
+	/*
+	 * If this is a fake page from the device_pager, but it covers actual
+	 * physical memory, convert to the real backing page.
+	 */
+	if ((m->flags & PG_FICTITIOUS) != 0) {
+		real = vm_phys_paddr_to_vm_page(pa);
+		if (real != NULL)
+			m = real;
+	}
+
+	CTR6(KTR_PMAP,
+	    "pmap_enter_locked: ctx=%p m=%p va=%#lx pa=%#lx prot=%#x wired=%d",
+	    pm->pm_context[curcpu], m, va, pa, prot, wired);
+
+	/*
+	 * If there is an existing mapping, and the physical address has not
+	 * changed, must be protection or wiring change.
+	 */
+	if ((tp = tsb_tte_lookup(pm, va)) != NULL && TTE_GET_PA(tp) == pa) {
+		CTR0(KTR_PMAP, "pmap_enter_locked: update");
+		PMAP_STATS_INC(pmap_nenter_update);
+
+		/*
+		 * Wiring change, just update stats.
+		 */
+		if (wired) {
+			if ((tp->tte_data & TD_WIRED) == 0) {
+				tp->tte_data |= TD_WIRED;
+				pm->pm_stats.wired_count++;
+			}
+		} else {
+			if ((tp->tte_data & TD_WIRED) != 0) {
+				tp->tte_data &= ~TD_WIRED;
+				pm->pm_stats.wired_count--;
+			}
+		}
+
+		/*
+		 * Save the old bits and clear the ones we're interested in.
+		 */
+		data = tp->tte_data;
+		tp->tte_data &= ~(TD_EXEC | TD_SW | TD_W);
+
+		/*
+		 * If we're turning off write permissions, sense modify status.
+		 */
+		if ((prot & VM_PROT_WRITE) != 0) {
+			tp->tte_data |= TD_SW;
+			if (wired)
+				tp->tte_data |= TD_W;
+			if ((m->oflags & VPO_UNMANAGED) == 0)
+				vm_page_aflag_set(m, PGA_WRITEABLE);
+		} else if ((data & TD_W) != 0)
+			vm_page_dirty(m);
+
+		/*
+		 * If we're turning on execute permissions, flush the icache.
+		 */
+		if ((prot & VM_PROT_EXECUTE) != 0) {
+			if ((data & TD_EXEC) == 0)
+				icache_page_inval(pa);
+			tp->tte_data |= TD_EXEC;
+		}
+
+		/*
+		 * Delete the old mapping.
+		 */
+		tlb_page_demap(pm, TTE_GET_VA(tp));
+	} else {
+		/*
+		 * If there is an existing mapping, but its for a different
+		 * physical address, delete the old mapping.
+		 */
+		if (tp != NULL) {
+			CTR0(KTR_PMAP, "pmap_enter_locked: replace");
+			PMAP_STATS_INC(pmap_nenter_replace);
+			pmap_remove_tte(pm, NULL, tp, va);
+			tlb_page_demap(pm, va);
+		} else {
+			CTR0(KTR_PMAP, "pmap_enter_locked: new");
+			PMAP_STATS_INC(pmap_nenter_new);
+		}
+
+		/*
+		 * Now set up the data and install the new mapping.
+		 */
+		data = TD_V | TD_8K | TD_PA(pa);
+		if (pm == kernel_pmap)
+			data |= TD_P;
+		if ((prot & VM_PROT_WRITE) != 0) {
+			data |= TD_SW;
+			if ((m->oflags & VPO_UNMANAGED) == 0)
+				vm_page_aflag_set(m, PGA_WRITEABLE);
+		}
+		if (prot & VM_PROT_EXECUTE) {
+			data |= TD_EXEC;
+			icache_page_inval(pa);
+		}
+
+		/*
+		 * If its wired update stats.  We also don't need reference or
+		 * modify tracking for wired mappings, so set the bits now.
+		 */
+		if (wired) {
+			pm->pm_stats.wired_count++;
+			data |= TD_REF | TD_WIRED;
+			if ((prot & VM_PROT_WRITE) != 0)
+				data |= TD_W;
+		}
+
+		tsb_tte_enter(pm, m, va, TS_8K, data);
+	}
+
+	return (KERN_SUCCESS);
+}
+
+/*
+ * Maps a sequence of resident pages belonging to the same object.
+ * The sequence begins with the given page m_start.  This page is
+ * mapped at the given virtual address start.  Each subsequent page is
+ * mapped at a virtual address that is offset from start by the same
+ * amount as the page is offset from m_start within the object.  The
+ * last page in the sequence is the page with the largest offset from
+ * m_start that can be mapped at a virtual address less than the given
+ * virtual address end.  Not every virtual page between start and end
+ * is mapped; only those for which a resident page exists with the
+ * corresponding offset from m_start are mapped.
+ */
+void
+pmap_enter_object(pmap_t pm, vm_offset_t start, vm_offset_t end,
+    vm_page_t m_start, vm_prot_t prot)
+{
+	vm_page_t m;
+	vm_pindex_t diff, psize;
+
+	VM_OBJECT_ASSERT_LOCKED(m_start->object);
+
+	psize = atop(end - start);
+	m = m_start;
+	rw_wlock(&tte_list_global_lock);
+	PMAP_LOCK(pm);
+	while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
+		pmap_enter_locked(pm, start + ptoa(diff), m, prot &
+		    (VM_PROT_READ | VM_PROT_EXECUTE), 0, 0);
+		m = TAILQ_NEXT(m, listq);
+	}
+	rw_wunlock(&tte_list_global_lock);
+	PMAP_UNLOCK(pm);
+}
+
+void
+pmap_enter_quick(pmap_t pm, vm_offset_t va, vm_page_t m, vm_prot_t prot)
+{
+
+	rw_wlock(&tte_list_global_lock);
+	PMAP_LOCK(pm);
+	pmap_enter_locked(pm, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE),
+	    0, 0);
+	rw_wunlock(&tte_list_global_lock);
+	PMAP_UNLOCK(pm);
+}
+
+void
+pmap_object_init_pt(pmap_t pm, vm_offset_t addr, vm_object_t object,
+    vm_pindex_t pindex, vm_size_t size)
+{
+
+	VM_OBJECT_ASSERT_WLOCKED(object);
+	KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG,
+	    ("pmap_object_init_pt: non-device object"));
+}
+
+static int
+pmap_unwire_tte(pmap_t pm, pmap_t pm2, struct tte *tp, vm_offset_t va)
+{
+
+	PMAP_LOCK_ASSERT(pm, MA_OWNED);
+	if ((tp->tte_data & TD_WIRED) == 0)
+		panic("pmap_unwire_tte: tp %p is missing TD_WIRED", tp);
+	atomic_clear_long(&tp->tte_data, TD_WIRED);
+	pm->pm_stats.wired_count--;
+	return (1);
+}
+
+/*
+ * Clear the wired attribute from the mappings for the specified range of
+ * addresses in the given pmap.  Every valid mapping within that range must
+ * have the wired attribute set.  In contrast, invalid mappings cannot have
+ * the wired attribute set, so they are ignored.
+ *
+ * The wired attribute of the translation table entry is not a hardware
+ * feature, so there is no need to invalidate any TLB entries.
+ */
+void
+pmap_unwire(pmap_t pm, vm_offset_t sva, vm_offset_t eva)
+{
+	vm_offset_t va;
+	struct tte *tp;
+
+	PMAP_LOCK(pm);
+	if (eva - sva > PMAP_TSB_THRESH)
+		tsb_foreach(pm, NULL, sva, eva, pmap_unwire_tte);
+	else {
+		for (va = sva; va < eva; va += PAGE_SIZE)
+			if ((tp = tsb_tte_lookup(pm, va)) != NULL)
+				pmap_unwire_tte(pm, NULL, tp, va);
+	}
+	PMAP_UNLOCK(pm);
+}
+
+static int
+pmap_copy_tte(pmap_t src_pmap, pmap_t dst_pmap, struct tte *tp,
+    vm_offset_t va)
+{
+	vm_page_t m;
+	u_long data;
+
+	if ((tp->tte_data & TD_FAKE) != 0)
+		return (1);
+	if (tsb_tte_lookup(dst_pmap, va) == NULL) {
+		data = tp->tte_data &
+		    ~(TD_PV | TD_REF | TD_SW | TD_CV | TD_W);
+		m = PHYS_TO_VM_PAGE(TTE_GET_PA(tp));
+		tsb_tte_enter(dst_pmap, m, va, TS_8K, data);
+	}
+	return (1);
+}
+
+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)
+{
+	struct tte *tp;
+	vm_offset_t va;
+
+	if (dst_addr != src_addr)
+		return;
+	rw_wlock(&tte_list_global_lock);
+	if (dst_pmap < src_pmap) {
+		PMAP_LOCK(dst_pmap);
+		PMAP_LOCK(src_pmap);
+	} else {
+		PMAP_LOCK(src_pmap);
+		PMAP_LOCK(dst_pmap);
+	}
+	if (len > PMAP_TSB_THRESH) {
+		tsb_foreach(src_pmap, dst_pmap, src_addr, src_addr + len,
+		    pmap_copy_tte);
+		tlb_context_demap(dst_pmap);
+	} else {
+		for (va = src_addr; va < src_addr + len; va += PAGE_SIZE)
+			if ((tp = tsb_tte_lookup(src_pmap, va)) != NULL)
+				pmap_copy_tte(src_pmap, dst_pmap, tp, va);
+		tlb_range_demap(dst_pmap, src_addr, src_addr + len - 1);
+	}
+	rw_wunlock(&tte_list_global_lock);
+	PMAP_UNLOCK(src_pmap);
+	PMAP_UNLOCK(dst_pmap);
+}
+
+void
+pmap_zero_page(vm_page_t m)
+{
+	struct tte *tp;
+	vm_offset_t va;
+	vm_paddr_t pa;
+
+	KASSERT((m->flags & PG_FICTITIOUS) == 0,
+	    ("pmap_zero_page: fake page"));
+	PMAP_STATS_INC(pmap_nzero_page);
+	pa = VM_PAGE_TO_PHYS(m);
+	if (dcache_color_ignore != 0 || m->md.color == DCACHE_COLOR(pa)) {
+		PMAP_STATS_INC(pmap_nzero_page_c);
+		va = TLB_PHYS_TO_DIRECT(pa);
+		cpu_block_zero((void *)va, PAGE_SIZE);
+	} else if (m->md.color == -1) {
+		PMAP_STATS_INC(pmap_nzero_page_nc);
+		aszero(ASI_PHYS_USE_EC, pa, PAGE_SIZE);
+	} else {
+		PMAP_STATS_INC(pmap_nzero_page_oc);
+		PMAP_LOCK(kernel_pmap);
+		va = pmap_temp_map_1 + (m->md.color * PAGE_SIZE);
+		tp = tsb_kvtotte(va);
+		tp->tte_data = TD_V | TD_8K | TD_PA(pa) | TD_CP | TD_CV | TD_W;
+		tp->tte_vpn = TV_VPN(va, TS_8K);
+		cpu_block_zero((void *)va, PAGE_SIZE);
+		tlb_page_demap(kernel_pmap, va);
+		PMAP_UNLOCK(kernel_pmap);
+	}
+}
+
+void
+pmap_zero_page_area(vm_page_t m, int off, int size)
+{
+	struct tte *tp;
+	vm_offset_t va;
+	vm_paddr_t pa;
+
+	KASSERT((m->flags & PG_FICTITIOUS) == 0,
+	    ("pmap_zero_page_area: fake page"));
+	KASSERT(off + size <= PAGE_SIZE, ("pmap_zero_page_area: bad off/size"));
+	PMAP_STATS_INC(pmap_nzero_page_area);
+	pa = VM_PAGE_TO_PHYS(m);
+	if (dcache_color_ignore != 0 || m->md.color == DCACHE_COLOR(pa)) {
+		PMAP_STATS_INC(pmap_nzero_page_area_c);
+		va = TLB_PHYS_TO_DIRECT(pa);
+		bzero((void *)(va + off), size);
+	} else if (m->md.color == -1) {
+		PMAP_STATS_INC(pmap_nzero_page_area_nc);
+		aszero(ASI_PHYS_USE_EC, pa + off, size);
+	} else {
+		PMAP_STATS_INC(pmap_nzero_page_area_oc);
+		PMAP_LOCK(kernel_pmap);
+		va = pmap_temp_map_1 + (m->md.color * PAGE_SIZE);
+		tp = tsb_kvtotte(va);
+		tp->tte_data = TD_V | TD_8K | TD_PA(pa) | TD_CP | TD_CV | TD_W;
+		tp->tte_vpn = TV_VPN(va, TS_8K);
+		bzero((void *)(va + off), size);
+		tlb_page_demap(kernel_pmap, va);
+		PMAP_UNLOCK(kernel_pmap);
+	}
+}
+
+void
+pmap_zero_page_idle(vm_page_t m)
+{
+	struct tte *tp;
+	vm_offset_t va;
+	vm_paddr_t pa;
+
+	KASSERT((m->flags & PG_FICTITIOUS) == 0,
+	    ("pmap_zero_page_idle: fake page"));
+	PMAP_STATS_INC(pmap_nzero_page_idle);
+	pa = VM_PAGE_TO_PHYS(m);
+	if (dcache_color_ignore != 0 || m->md.color == DCACHE_COLOR(pa)) {
+		PMAP_STATS_INC(pmap_nzero_page_idle_c);
+		va = TLB_PHYS_TO_DIRECT(pa);
+		cpu_block_zero((void *)va, PAGE_SIZE);
+	} else if (m->md.color == -1) {
+		PMAP_STATS_INC(pmap_nzero_page_idle_nc);
+		aszero(ASI_PHYS_USE_EC, pa, PAGE_SIZE);
+	} else {
+		PMAP_STATS_INC(pmap_nzero_page_idle_oc);
+		va = pmap_idle_map + (m->md.color * PAGE_SIZE);
+		tp = tsb_kvtotte(va);
+		tp->tte_data = TD_V | TD_8K | TD_PA(pa) | TD_CP | TD_CV | TD_W;
+		tp->tte_vpn = TV_VPN(va, TS_8K);
+		cpu_block_zero((void *)va, PAGE_SIZE);
+		tlb_page_demap(kernel_pmap, va);
+	}
+}
+
+void
+pmap_copy_page(vm_page_t msrc, vm_page_t mdst)
+{
+	vm_offset_t vdst;
+	vm_offset_t vsrc;
+	vm_paddr_t pdst;
+	vm_paddr_t psrc;
+	struct tte *tp;
+
+	KASSERT((mdst->flags & PG_FICTITIOUS) == 0,
+	    ("pmap_copy_page: fake dst page"));
+	KASSERT((msrc->flags & PG_FICTITIOUS) == 0,
+	    ("pmap_copy_page: fake src page"));
+	PMAP_STATS_INC(pmap_ncopy_page);
+	pdst = VM_PAGE_TO_PHYS(mdst);
+	psrc = VM_PAGE_TO_PHYS(msrc);
+	if (dcache_color_ignore != 0 ||
+	    (msrc->md.color == DCACHE_COLOR(psrc) &&
+	    mdst->md.color == DCACHE_COLOR(pdst))) {
+		PMAP_STATS_INC(pmap_ncopy_page_c);
+		vdst = TLB_PHYS_TO_DIRECT(pdst);
+		vsrc = TLB_PHYS_TO_DIRECT(psrc);
+		cpu_block_copy((void *)vsrc, (void *)vdst, PAGE_SIZE);
+	} else if (msrc->md.color == -1 && mdst->md.color == -1) {
+		PMAP_STATS_INC(pmap_ncopy_page_nc);
+		ascopy(ASI_PHYS_USE_EC, psrc, pdst, PAGE_SIZE);
+	} else if (msrc->md.color == -1) {
+		if (mdst->md.color == DCACHE_COLOR(pdst)) {
+			PMAP_STATS_INC(pmap_ncopy_page_dc);
+			vdst = TLB_PHYS_TO_DIRECT(pdst);
+			ascopyfrom(ASI_PHYS_USE_EC, psrc, (void *)vdst,
+			    PAGE_SIZE);
+		} else {
+			PMAP_STATS_INC(pmap_ncopy_page_doc);
+			PMAP_LOCK(kernel_pmap);
+			vdst = pmap_temp_map_1 + (mdst->md.color * PAGE_SIZE);
+			tp = tsb_kvtotte(vdst);
+			tp->tte_data =
+			    TD_V | TD_8K | TD_PA(pdst) | TD_CP | TD_CV | TD_W;
+			tp->tte_vpn = TV_VPN(vdst, TS_8K);
+			ascopyfrom(ASI_PHYS_USE_EC, psrc, (void *)vdst,
+			    PAGE_SIZE);
+			tlb_page_demap(kernel_pmap, vdst);
+			PMAP_UNLOCK(kernel_pmap);
+		}
+	} else if (mdst->md.color == -1) {
+		if (msrc->md.color == DCACHE_COLOR(psrc)) {
+			PMAP_STATS_INC(pmap_ncopy_page_sc);
+			vsrc = TLB_PHYS_TO_DIRECT(psrc);
+			ascopyto((void *)vsrc, ASI_PHYS_USE_EC, pdst,
+			    PAGE_SIZE);
+		} else {
+			PMAP_STATS_INC(pmap_ncopy_page_soc);
+			PMAP_LOCK(kernel_pmap);
+			vsrc = pmap_temp_map_1 + (msrc->md.color * PAGE_SIZE);
+			tp = tsb_kvtotte(vsrc);
+			tp->tte_data =
+			    TD_V | TD_8K | TD_PA(psrc) | TD_CP | TD_CV | TD_W;
+			tp->tte_vpn = TV_VPN(vsrc, TS_8K);
+			ascopyto((void *)vsrc, ASI_PHYS_USE_EC, pdst,
+			    PAGE_SIZE);
+			tlb_page_demap(kernel_pmap, vsrc);
+			PMAP_UNLOCK(kernel_pmap);
+		}
+	} else {
+		PMAP_STATS_INC(pmap_ncopy_page_oc);
+		PMAP_LOCK(kernel_pmap);
+		vdst = pmap_temp_map_1 + (mdst->md.color * PAGE_SIZE);
+		tp = tsb_kvtotte(vdst);
+		tp->tte_data =
+		    TD_V | TD_8K | TD_PA(pdst) | TD_CP | TD_CV | TD_W;
+		tp->tte_vpn = TV_VPN(vdst, TS_8K);
+		vsrc = pmap_temp_map_2 + (msrc->md.color * PAGE_SIZE);
+		tp = tsb_kvtotte(vsrc);
+		tp->tte_data =
+		    TD_V | TD_8K | TD_PA(psrc) | TD_CP | TD_CV | TD_W;
+		tp->tte_vpn = TV_VPN(vsrc, TS_8K);
+		cpu_block_copy((void *)vsrc, (void *)vdst, PAGE_SIZE);
+		tlb_page_demap(kernel_pmap, vdst);
+		tlb_page_demap(kernel_pmap, vsrc);
+		PMAP_UNLOCK(kernel_pmap);
+	}
+}
+
+int unmapped_buf_allowed;
+
+void
+pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
+    vm_offset_t b_offset, int xfersize)
+{
+
+	panic("pmap_copy_pages: not implemented");
+}
+
+/*
+ * Returns true if the pmap's pv is one of the first
+ * 16 pvs linked to from this page.  This count may
+ * be changed upwards or downwards in the future; it
+ * is only necessary that true be returned for a small
+ * subset of pmaps for proper page aging.
+ */
+boolean_t
+pmap_page_exists_quick(pmap_t pm, vm_page_t m)
+{
+	struct tte *tp;
+	int loops;
+	boolean_t rv;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_page_exists_quick: page %p is not managed", m));
+	loops = 0;
+	rv = FALSE;
+	rw_wlock(&tte_list_global_lock);
+	TAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
+		if ((tp->tte_data & TD_PV) == 0)
+			continue;
+		if (TTE_GET_PMAP(tp) == pm) {
+			rv = TRUE;
+			break;
+		}
+		if (++loops >= 16)
+			break;
+	}
+	rw_wunlock(&tte_list_global_lock);
+	return (rv);
+}
+
+/*
+ * Return the number of managed mappings to the given physical page
+ * that are wired.
+ */
+int
+pmap_page_wired_mappings(vm_page_t m)
+{
+	struct tte *tp;
+	int count;
+
+	count = 0;
+	if ((m->oflags & VPO_UNMANAGED) != 0)
+		return (count);
+	rw_wlock(&tte_list_global_lock);
+	TAILQ_FOREACH(tp, &m->md.tte_list, tte_link)
+		if ((tp->tte_data & (TD_PV | TD_WIRED)) == (TD_PV | TD_WIRED))
+			count++;
+	rw_wunlock(&tte_list_global_lock);
+	return (count);
+}
+
+/*
+ * Remove all pages from specified address space, this aids process exit
+ * speeds.  This is much faster than pmap_remove in the case of running down
+ * an entire address space.  Only works for the current pmap.
+ */
+void
+pmap_remove_pages(pmap_t pm)
+{
+
+}
+
+/*
+ * Returns TRUE if the given page has a managed mapping.
+ */
+boolean_t
+pmap_page_is_mapped(vm_page_t m)
+{
+	struct tte *tp;
+	boolean_t rv;
+
+	rv = FALSE;
+	if ((m->oflags & VPO_UNMANAGED) != 0)
+		return (rv);
+	rw_wlock(&tte_list_global_lock);
+	TAILQ_FOREACH(tp, &m->md.tte_list, tte_link)
+		if ((tp->tte_data & TD_PV) != 0) {
+			rv = TRUE;
+			break;
+		}
+	rw_wunlock(&tte_list_global_lock);
+	return (rv);
+}
+
+/*
+ * Return a count of reference bits for a page, clearing those bits.
+ * It is not necessary for every reference bit to be cleared, but it
+ * is necessary that 0 only be returned when there are truly no
+ * reference bits set.
+ *
+ * XXX: The exact number of bits to check and clear is a matter that
+ * should be tested and standardized at some point in the future for
+ * optimal aging of shared pages.
+ */
+int
+pmap_ts_referenced(vm_page_t m)
+{
+	struct tte *tpf;
+	struct tte *tpn;
+	struct tte *tp;
+	u_long data;
+	int count;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_ts_referenced: page %p is not managed", m));
+	count = 0;
+	rw_wlock(&tte_list_global_lock);
+	if ((tp = TAILQ_FIRST(&m->md.tte_list)) != NULL) {
+		tpf = tp;
+		do {
+			tpn = TAILQ_NEXT(tp, tte_link);
+			TAILQ_REMOVE(&m->md.tte_list, tp, tte_link);
+			TAILQ_INSERT_TAIL(&m->md.tte_list, tp, tte_link);
+			if ((tp->tte_data & TD_PV) == 0)
+				continue;
+			data = atomic_clear_long(&tp->tte_data, TD_REF);
+			if ((data & TD_REF) != 0 && ++count > 4)
+				break;
+		} while ((tp = tpn) != NULL && tp != tpf);
+	}
+	rw_wunlock(&tte_list_global_lock);
+	return (count);
+}
+
+boolean_t
+pmap_is_modified(vm_page_t m)
+{
+	struct tte *tp;
+	boolean_t rv;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_is_modified: page %p is not managed", m));
+	rv = FALSE;
+
+	/*
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
+	 * concurrently set while the object is locked.  Thus, if PGA_WRITEABLE
+	 * is clear, no TTEs can have TD_W set.
+	 */
+	VM_OBJECT_ASSERT_WLOCKED(m->object);
+	if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
+		return (rv);
+	rw_wlock(&tte_list_global_lock);
+	TAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
+		if ((tp->tte_data & TD_PV) == 0)
+			continue;
+		if ((tp->tte_data & TD_W) != 0) {
+			rv = TRUE;
+			break;
+		}
+	}
+	rw_wunlock(&tte_list_global_lock);
+	return (rv);
+}
+
+/*
+ *	pmap_is_prefaultable:
+ *
+ *	Return whether or not the specified virtual address is elgible
+ *	for prefault.
+ */
+boolean_t
+pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
+{
+	boolean_t rv;
+
+	PMAP_LOCK(pmap);
+	rv = tsb_tte_lookup(pmap, addr) == NULL;
+	PMAP_UNLOCK(pmap);
+	return (rv);
+}
+
+/*
+ * Return whether or not the specified physical page was referenced
+ * in any physical maps.
+ */
+boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+	struct tte *tp;
+	boolean_t rv;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_is_referenced: page %p is not managed", m));
+	rv = FALSE;
+	rw_wlock(&tte_list_global_lock);
+	TAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
+		if ((tp->tte_data & TD_PV) == 0)
+			continue;
+		if ((tp->tte_data & TD_REF) != 0) {
+			rv = TRUE;
+			break;
+		}
+	}
+	rw_wunlock(&tte_list_global_lock);
+	return (rv);
+}
+
+/*
+ * This function is advisory.
+ */
+void
+pmap_advise(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, int advice)
+{
+}
+
+void
+pmap_clear_modify(vm_page_t m)
+{
+	struct tte *tp;
+	u_long data;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_clear_modify: page %p is not managed", m));
+	VM_OBJECT_ASSERT_WLOCKED(m->object);
+	KASSERT(!vm_page_xbusied(m),
+	    ("pmap_clear_modify: page %p is exclusive busied", m));
+
+	/*
+	 * If the page is not PGA_WRITEABLE, then no TTEs can have TD_W set.
+	 * If the object containing the page is locked and the page is not
+	 * exclusive busied, then PGA_WRITEABLE cannot be concurrently set.
+	 */
+	if ((m->aflags & PGA_WRITEABLE) == 0)
+		return;
+	rw_wlock(&tte_list_global_lock);
+	TAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
+		if ((tp->tte_data & TD_PV) == 0)
+			continue;
+		data = atomic_clear_long(&tp->tte_data, TD_W);
+		if ((data & TD_W) != 0)
+			tlb_page_demap(TTE_GET_PMAP(tp), TTE_GET_VA(tp));
+	}
+	rw_wunlock(&tte_list_global_lock);
+}
+
+void
+pmap_remove_write(vm_page_t m)
+{
+	struct tte *tp;
+	u_long data;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_remove_write: page %p is not managed", m));
+
+	/*
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
+	 * set by another thread while the object is locked.  Thus,
+	 * if PGA_WRITEABLE is clear, no page table entries need updating.
+	 */
+	VM_OBJECT_ASSERT_WLOCKED(m->object);
+	if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
+		return;
+	rw_wlock(&tte_list_global_lock);
+	TAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
+		if ((tp->tte_data & TD_PV) == 0)
+			continue;
+		data = atomic_clear_long(&tp->tte_data, TD_SW | TD_W);
+		if ((data & TD_W) != 0) {
+			vm_page_dirty(m);
+			tlb_page_demap(TTE_GET_PMAP(tp), TTE_GET_VA(tp));
+		}
+	}
+	vm_page_aflag_clear(m, PGA_WRITEABLE);
+	rw_wunlock(&tte_list_global_lock);
+}
+
+int
+pmap_mincore(pmap_t pm, vm_offset_t addr, vm_paddr_t *locked_pa)
+{
+
+	/* TODO; */
+	return (0);
+}
+
+/*
+ * Activate a user pmap.  The pmap must be activated before its address space
+ * can be accessed in any way.
+ */
+void
+pmap_activate(struct thread *td)
+{
+	struct vmspace *vm;
+	struct pmap *pm;
+	int context;
+
+	critical_enter();
+	vm = td->td_proc->p_vmspace;
+	pm = vmspace_pmap(vm);
+
+	context = PCPU_GET(tlb_ctx);
+	if (context == PCPU_GET(tlb_ctx_max)) {
+		tlb_flush_user();
+		context = PCPU_GET(tlb_ctx_min);
+	}
+	PCPU_SET(tlb_ctx, context + 1);
+
+	pm->pm_context[curcpu] = context;
+#ifdef SMP
+	CPU_SET_ATOMIC(PCPU_GET(cpuid), &pm->pm_active);
+	atomic_store_acq_ptr((uintptr_t *)PCPU_PTR(pmap), (uintptr_t)pm);
+#else
+	CPU_SET(PCPU_GET(cpuid), &pm->pm_active);
+	PCPU_SET(pmap, pm);
+#endif
+
+	stxa(AA_DMMU_TSB, ASI_DMMU, pm->pm_tsb);
+	stxa(AA_IMMU_TSB, ASI_IMMU, pm->pm_tsb);
+	stxa(AA_DMMU_PCXR, ASI_DMMU, (ldxa(AA_DMMU_PCXR, ASI_DMMU) &
+	    TLB_CXR_PGSZ_MASK) | context);
+	flush(KERNBASE);
+	critical_exit();
+}
+
+void
+pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+
+}
+
+/*
+ * Increase the starting virtual address of the given mapping if a
+ * different alignment might result in more superpage mappings.
+ */
+void
+pmap_align_superpage(vm_object_t object, vm_ooffset_t offset,
+    vm_offset_t *addr, vm_size_t size)
+{
+
+}


Property changes on: trunk/sys/sparc64/sparc64/pmap.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/prof_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/prof_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/prof_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,85 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1996 Bruce D. Evans.
+ * Copyright (c) 2002 by Thomas Moestl <tmm at 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, 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.
+ *
+ *	from: src/sys/i386/isa/prof_machdep.c,v 1.16 2000/07/04 11:25:19
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/prof_machdep.c 181701 2008-08-13 20:30:28Z marius $");
+
+#ifdef GUPROF
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/gmon.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+
+#include <machine/profile.h>
+
+int	cputime_bias;
+
+/*
+ * Return the time elapsed since the last call.  The units are machine-
+ * dependent.
+ * XXX: this is not SMP-safe.  It should use per-CPU variables; %tick can be
+ * used though.
+ */
+int
+cputime(void)
+{
+	u_long count;
+	static u_long prev_count;
+	int delta;
+
+	count = rd(tick);
+	delta = (int)(count - prev_count);
+	prev_count = count;
+	return (delta);
+}
+
+/*
+ * The start and stop routines need not be here since we turn off profiling
+ * before calling them.  They are here for convenience.
+ */
+void
+startguprof(struct gmonparam *gp)
+{
+
+	gp->profrate = tick_freq;
+	cputime_bias = 0;
+	cputime();
+}
+
+void
+stopguprof(struct gmonparam *gp)
+{
+
+	/* Nothing to do. */
+}
+
+#endif /* GUPROF */


Property changes on: trunk/sys/sparc64/sparc64/prof_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/rtc.c
===================================================================
--- trunk/sys/sparc64/sparc64/rtc.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/rtc.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,253 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/rtc.c 227848 2011-11-22 21:55:40Z marius $");
+
+/*
+ * The `rtc' device is found on the ISA bus and the EBus.  The ISA version
+ * always is a MC146818 compatible clock while the EBus variant either is the
+ * MC146818 compatible Real-Time Clock function of a National Semiconductor
+ * PC87317/PC97317 which also provides Advanced Power Control functionality
+ * or a Texas Instruments bq4802.
+ */
+
+#include "opt_isa.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+
+#include <dev/ofw/ofw_bus.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <sys/rman.h>
+
+#include <isa/isavar.h>
+
+#include <dev/mc146818/mc146818reg.h>
+#include <dev/mc146818/mc146818var.h>
+
+#include "clock_if.h"
+
+#define	RTC_DESC	"Real-Time Clock"
+
+#define	RTC_READ	mc146818_def_read
+#define	RTC_WRITE	mc146818_def_write
+
+#define	PC87317_COMMON		MC_REGA_DV0	/* bank 0 */
+#define	PC87317_RTC		(MC_REGA_DV1 | MC_REGA_DV0) /* bank 1 */
+#define	PC87317_RTC_CR		0x48		/* Century Register */
+#define	PC87317_APC		MC_REGA_DV2	/* bank 2 */
+#define	PC87317_APC_CADDR	0x51		/* Century Address Register */
+#define	PC87317_APC_CADDR_BANK0	0x00		/* locate CR in bank 0 */
+#define	PC87317_APC_CADDR_BANK1	0x80		/* locate CR in bank 1 */
+
+static devclass_t rtc_devclass;
+
+static device_attach_t rtc_attach;
+static device_probe_t rtc_ebus_probe;
+#ifdef DEV_ISA
+static device_probe_t rtc_isa_probe;
+#endif
+
+static device_method_t rtc_ebus_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		rtc_ebus_probe),
+	DEVMETHOD(device_attach,	rtc_attach),
+
+	/* clock interface */
+	DEVMETHOD(clock_gettime,	mc146818_gettime),
+	DEVMETHOD(clock_settime,	mc146818_settime),
+
+	DEVMETHOD_END
+};
+
+static driver_t rtc_ebus_driver = {
+	"rtc",
+	rtc_ebus_methods,
+	sizeof(struct mc146818_softc),
+};
+
+DRIVER_MODULE(rtc, ebus, rtc_ebus_driver, rtc_devclass, 0, 0);
+
+#ifdef DEV_ISA
+static device_method_t rtc_isa_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		rtc_isa_probe),
+	DEVMETHOD(device_attach,	rtc_attach),
+
+	/* clock interface */
+	DEVMETHOD(clock_gettime,	mc146818_gettime),
+	DEVMETHOD(clock_settime,	mc146818_settime),
+
+	DEVMETHOD_END
+};
+
+static driver_t rtc_isa_driver = {
+	"rtc",
+	rtc_isa_methods,
+	sizeof(struct mc146818_softc),
+};
+
+DRIVER_MODULE(rtc, isa, rtc_isa_driver, rtc_devclass, 0, 0);
+#endif
+
+static u_int pc87317_getcent(device_t dev);
+static void pc87317_setcent(device_t dev, u_int cent);
+
+static int
+rtc_ebus_probe(device_t dev)
+{
+
+	if (strcmp(ofw_bus_get_name(dev), "rtc") == 0) {
+		/* The bq4802 is not supported, yet. */
+		if (ofw_bus_get_compat(dev) != NULL &&
+		    strcmp(ofw_bus_get_compat(dev), "bq4802") == 0)
+			return (ENXIO);
+		device_set_desc(dev, RTC_DESC);
+		return (0);
+	}
+
+	return (ENXIO);
+}
+
+#ifdef DEV_ISA
+static struct isa_pnp_id rtc_isa_ids[] = {
+	{ 0x000bd041, RTC_DESC }, /* PNP0B00 */
+	{ 0 }
+};
+
+static int
+rtc_isa_probe(device_t dev)
+{
+
+	if (ISA_PNP_PROBE(device_get_parent(dev), dev, rtc_isa_ids) == 0)
+		return (0);
+
+	return (ENXIO);
+}
+#endif
+
+static int
+rtc_attach(device_t dev)
+{
+	struct timespec ts;
+	struct mc146818_softc *sc;
+	struct resource *res;
+	int ebus, error, rid;
+
+	sc = device_get_softc(dev);
+
+	mtx_init(&sc->sc_mtx, "rtc_mtx", NULL, MTX_SPIN);
+
+	ebus = 0;
+	if (strcmp(device_get_name(device_get_parent(dev)), "ebus") == 0)
+		ebus = 1;
+
+	rid = 0;
+	res = bus_alloc_resource_any(dev, ebus ? SYS_RES_MEMORY :
+	    SYS_RES_IOPORT, &rid, RF_ACTIVE);
+	if (res == NULL) {
+		device_printf(dev, "cannot allocate resources\n");
+		error = ENXIO;
+		goto fail_mtx;
+	}
+	sc->sc_bst = rman_get_bustag(res);
+	sc->sc_bsh = rman_get_bushandle(res);
+
+	sc->sc_mcread = RTC_READ;
+	sc->sc_mcwrite = RTC_WRITE;
+	/* The TOD clock year 0 is 0. */
+	sc->sc_year0 = 0;
+	/*
+	 * For ISA use the default century get/set functions, for EBus we
+	 * provide our own versions.
+	 */
+	sc->sc_flag = MC146818_NO_CENT_ADJUST;
+	if (ebus) {
+		/*
+		 * Make sure the CR is at the default location (also used
+		 * by Solaris).
+		 */
+		RTC_WRITE(dev, MC_REGA, PC87317_APC);
+		RTC_WRITE(dev, PC87317_APC_CADDR, PC87317_APC_CADDR_BANK1 |
+		    PC87317_RTC_CR);
+		RTC_WRITE(dev, MC_REGA, PC87317_COMMON);
+		sc->sc_getcent = pc87317_getcent;
+		sc->sc_setcent = pc87317_setcent;
+	}
+	if ((error = mc146818_attach(dev)) != 0) {
+		device_printf(dev, "cannot attach time of day clock\n");
+		goto fail_res;
+	}
+
+	if (bootverbose) {
+		if (mc146818_gettime(dev, &ts) != 0)
+			device_printf(dev, "invalid time");
+		else
+			device_printf(dev, "current time: %ld.%09ld\n",
+			    (long)ts.tv_sec, ts.tv_nsec);
+	}
+
+	return (0);
+
+ fail_res:
+	bus_release_resource(dev, ebus ? SYS_RES_MEMORY : SYS_RES_IOPORT, rid,
+	    res);
+ fail_mtx:
+	mtx_destroy(&sc->sc_mtx);
+
+	return (error);
+}
+
+static u_int
+pc87317_getcent(device_t dev)
+{
+	u_int cent;
+
+	RTC_WRITE(dev, MC_REGA, PC87317_RTC);
+	cent = RTC_READ(dev, PC87317_RTC_CR);
+	RTC_WRITE(dev, MC_REGA, PC87317_COMMON);
+	return (cent);
+}
+
+static void
+pc87317_setcent(device_t dev, u_int cent)
+{
+
+	RTC_WRITE(dev, MC_REGA, PC87317_RTC);
+	RTC_WRITE(dev, PC87317_RTC_CR, cent);
+	RTC_WRITE(dev, MC_REGA, PC87317_COMMON);
+}


Property changes on: trunk/sys/sparc64/sparc64/rtc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/rwindow.c
===================================================================
--- trunk/sys/sparc64/sparc64/rwindow.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/rwindow.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,111 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1997 Berkeley Software Design, Inc. 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. Berkeley Software Design Inc's name may not be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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: BSDI: trap.c,v 1.17.2.9 1999/10/19 15:29:52 cp Exp
+ * $FreeBSD: stable/10/sys/sparc64/sparc64/rwindow.c 138129 2004-11-27 06:51:39Z das $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ktr.h>
+#include <sys/proc.h>
+
+#include <machine/frame.h>
+#include <machine/pcb.h>
+
+CTASSERT((1 << RW_SHIFT) == sizeof(struct rwindow));
+
+int
+rwindow_load(struct thread *td, struct trapframe *tf, int n)
+{
+	struct rwindow rw;
+	u_long usp;
+	int error;
+	int i;
+
+	CTR3(KTR_TRAP, "rwindow_load: td=%p (%s) n=%d",
+	    td, td->td_proc->p_comm, n);
+
+	/*
+	 * In case current window is still only on-chip, push it out;
+	 * if it cannot get all the way out, we cannot continue either.
+	 */
+	if ((error = rwindow_save(td)) != 0)
+		return (error);
+	usp = tf->tf_out[6];
+	for (i = 0; i < n; i++) {
+		CTR1(KTR_TRAP, "rwindow_load: usp=%#lx", usp);
+		usp += SPOFF;
+		if ((error = (usp & 0x7)) != 0)
+			break;
+		error = copyin((void *)usp, &rw, sizeof rw);
+		usp = rw.rw_in[6];
+	}
+	CTR1(KTR_TRAP, "rwindow_load: error=%d", error);
+	return (error == 0 ? 0 : SIGILL);
+}
+
+int
+rwindow_save(struct thread *td)
+{
+	struct rwindow *rw;
+	struct pcb *pcb;
+	u_long *ausp;
+	u_long usp;
+	int error;
+	int i;
+
+	pcb = td->td_pcb;
+	CTR3(KTR_TRAP, "rwindow_save: td=%p (%s) nsaved=%d", td,
+	    td->td_proc->p_comm, pcb->pcb_nsaved);
+
+	flushw();
+	KASSERT(pcb->pcb_nsaved < MAXWIN,
+	    ("rwindow_save: pcb_nsaved > MAXWIN"));
+	if ((i = pcb->pcb_nsaved) == 0)
+		return (0);
+	ausp = pcb->pcb_rwsp;
+	rw = pcb->pcb_rw;
+	error = 0;
+	do {
+		usp = *ausp;
+		CTR1(KTR_TRAP, "rwindow_save: usp=%#lx", usp);
+		usp += SPOFF;
+		if ((error = (usp & 0x7)) != 0)
+			break;
+		error = copyout(rw, (void *)usp, sizeof *rw);
+		if (error)
+			break;
+		ausp++;
+		rw++;
+	} while (--i > 0);
+	CTR1(KTR_TRAP, "rwindow_save: error=%d", error);
+	if (error == 0)
+		pcb->pcb_nsaved = 0;
+	return (error == 0 ? 0 : SIGILL);
+}


Property changes on: trunk/sys/sparc64/sparc64/rwindow.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/sc_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/sc_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/sc_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,152 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Jake Burkholder.
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/sc_machdep.c 227848 2011-11-22 21:55:40Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <sys/consio.h>
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/module.h>
+
+#include <dev/ofw/ofw_bus.h>
+
+#include <machine/bus.h>
+
+#include <dev/syscons/syscons.h>
+
+#define	SC_MD_MAX	8
+#define	SC_MD_FLAGS	SC_AUTODETECT_KBD
+
+static sc_softc_t sc_softcs[SC_MD_MAX];
+
+static device_identify_t sc_identify;
+static device_probe_t sc_probe;
+static device_attach_t sc_attach;
+
+static device_method_t sc_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_identify,	sc_identify),
+	DEVMETHOD(device_probe,		sc_probe),
+	DEVMETHOD(device_attach,	sc_attach),
+
+	DEVMETHOD_END
+};
+
+static driver_t sc_driver = {
+	SC_DRIVER_NAME,
+	sc_methods,
+	1,	/* no softc */
+};
+
+static devclass_t sc_devclass;
+
+DRIVER_MODULE(sc, nexus, sc_driver, sc_devclass, 0, 0);
+
+static void
+sc_identify(driver_t *driver, device_t parent)
+{
+
+	/*
+	 * Add with a priority guaranteed to make it last on
+	 * the device list.
+	 */
+	BUS_ADD_CHILD(parent, INT_MAX, SC_DRIVER_NAME, 0);
+}
+
+static int
+sc_probe(device_t dev)
+{
+	int unit;
+
+	unit = device_get_unit(dev);
+	if (strcmp(ofw_bus_get_name(dev), SC_DRIVER_NAME) != 0 ||
+	    unit >= SC_MD_MAX)
+		return (ENXIO);
+
+	device_set_desc(dev, "System console");
+	return (sc_probe_unit(unit, device_get_flags(dev) | SC_MD_FLAGS));
+}
+
+static int
+sc_attach(device_t dev)
+{
+
+	return (sc_attach_unit(device_get_unit(dev),
+	    device_get_flags(dev) | SC_MD_FLAGS));
+}
+
+int
+sc_get_cons_priority(int *unit, int *flags)
+{
+
+	*unit = 0;
+	*flags = 0;
+	return (CN_INTERNAL);
+}
+
+int
+sc_max_unit(void)
+{
+
+	return (devclass_get_maxunit(sc_devclass));
+}
+
+sc_softc_t *
+sc_get_softc(int unit, int flags)
+{
+	sc_softc_t *sc;
+
+	if (unit < 0 || unit >= SC_MD_MAX)
+		return (NULL);
+	sc = &sc_softcs[unit];
+	sc->unit = unit;
+	if ((sc->flags & SC_INIT_DONE) == 0) {
+		sc->keyboard = -1;
+		sc->adapter = -1;
+		sc->cursor_char = SC_CURSOR_CHAR;
+		sc->mouse_char = SC_MOUSE_CHAR;
+	}
+	return (sc);
+}
+
+void
+sc_get_bios_values(bios_values_t *values)
+{
+
+}
+
+int
+sc_tone(int hz)
+{
+
+	return (0);
+}


Property changes on: trunk/sys/sparc64/sparc64/sc_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/schppm.c
===================================================================
--- trunk/sys/sparc64/sparc64/schppm.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/schppm.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,133 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/schppm.c 227848 2011-11-22 21:55:40Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#define	SCHPPM_NREG	1
+
+#define	SCHPPM_ESTAR	0
+
+#define	SCHPPM_ESTAR_CTRL		0x00
+#define	SCHPPM_ESTAR_CTRL_1		0x00000001
+#define	SCHPPM_ESTAR_CTRL_2		0x00000002
+#define	SCHPPM_ESTAR_CTRL_32		0x00000020
+#define	SCHPPM_ESTAR_CTRL_MASK						\
+	(SCHPPM_ESTAR_CTRL_1 | SCHPPM_ESTAR_CTRL_2 | SCHPPM_ESTAR_CTRL_32)
+
+static struct resource_spec schppm_res_spec[] = {
+	{ SYS_RES_MEMORY, SCHPPM_ESTAR, RF_ACTIVE },
+	{ -1, 0 }
+};
+
+struct schppm_softc {
+	struct resource		*sc_res[SCHPPM_NREG];
+};
+
+#define	SCHPPM_READ(sc, reg, off)					\
+	bus_read_8((sc)->sc_res[(reg)], (off))
+#define	SCHPPM_WRITE(sc, reg, off, val)					\
+	bus_write_8((sc)->sc_res[(reg)], (off), (val))
+
+static device_probe_t schppm_probe;
+static device_attach_t schppm_attach;
+
+static device_method_t schppm_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		schppm_probe),
+	DEVMETHOD(device_attach,	schppm_attach),
+
+	DEVMETHOD_END
+};
+
+static devclass_t schppm_devclass;
+
+DEFINE_CLASS_0(schppm, schppm_driver, schppm_methods,
+    sizeof(struct schppm_softc));
+DRIVER_MODULE(schppm, nexus, schppm_driver, schppm_devclass, 0, 0);
+
+static int
+schppm_probe(device_t dev)
+{
+	const char* compat;
+
+	compat = ofw_bus_get_compat(dev);
+	if (compat != NULL && strcmp(ofw_bus_get_name(dev), "ppm") == 0 &&
+	    strcmp(compat, "gp2-ppm") == 0) {
+		device_set_desc(dev, "Schizo power management");
+		return (BUS_PROBE_DEFAULT);
+	}
+	return (ENXIO);
+}
+
+static int
+schppm_attach(device_t dev)
+{
+	struct schppm_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (bus_alloc_resources(dev, schppm_res_spec, sc->sc_res)) {
+		device_printf(dev, "failed to allocate resources\n");
+		bus_release_resources(dev, schppm_res_spec, sc->sc_res);
+		return (ENXIO);
+	}
+
+	if (bootverbose) {
+		device_printf(dev, "running at ");
+		switch (SCHPPM_READ(sc, SCHPPM_ESTAR, SCHPPM_ESTAR_CTRL) &
+		    SCHPPM_ESTAR_CTRL_MASK) {
+		case SCHPPM_ESTAR_CTRL_1:
+			printf("full");
+			break;
+		case SCHPPM_ESTAR_CTRL_2:
+			printf("half");
+			break;
+		case SCHPPM_ESTAR_CTRL_32:
+			printf("1/32");
+			break;
+		default:
+			printf("unknown");
+			break;
+		}
+		printf(" speed\n");
+	}
+
+	return (0);
+}


Property changes on: trunk/sys/sparc64/sparc64/schppm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/spitfire.c
===================================================================
--- trunk/sys/sparc64/sparc64/spitfire.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/spitfire.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,185 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Jake Burkholder.
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/spitfire.c 262620 2014-02-28 20:22:48Z dim $");
+
+#include "opt_pmap.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+#include <sys/sysctl.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/cache.h>
+#include <machine/cpufunc.h>
+#include <machine/lsu.h>
+#include <machine/smp.h>
+#include <machine/tlb.h>
+
+#define	SPITFIRE_TLB_ENTRIES	64
+
+PMAP_STATS_VAR(spitfire_dcache_npage_inval);
+PMAP_STATS_VAR(spitfire_dcache_npage_inval_match);
+PMAP_STATS_VAR(spitfire_icache_npage_inval);
+PMAP_STATS_VAR(spitfire_icache_npage_inval_match);
+
+/*
+ * Enable the level 1 caches.
+ */
+void
+spitfire_cache_enable(u_int cpu_impl __unused)
+{
+	u_long lsu;
+
+	lsu = ldxa(0, ASI_LSU_CTL_REG);
+	stxa_sync(0, ASI_LSU_CTL_REG, lsu | LSU_IC | LSU_DC);
+}
+
+/*
+ * Flush all lines from the level 1 caches.
+ */
+void
+spitfire_cache_flush(void)
+{
+	u_long addr;
+
+	for (addr = 0; addr < PCPU_GET(cache.dc_size);
+	    addr += PCPU_GET(cache.dc_linesize))
+		stxa_sync(addr, ASI_DCACHE_TAG, 0);
+	for (addr = 0; addr < PCPU_GET(cache.ic_size);
+	    addr += PCPU_GET(cache.ic_linesize))
+		stxa_sync(addr, ASI_ICACHE_TAG, 0);
+}
+
+/*
+ * Flush a physical page from the data cache.
+ */
+void
+spitfire_dcache_page_inval(vm_paddr_t pa)
+{
+	u_long target;
+	void *cookie;
+	u_long addr;
+	u_long tag;
+
+	KASSERT((pa & PAGE_MASK) == 0, ("%s: pa not page aligned", __func__));
+	PMAP_STATS_INC(spitfire_dcache_npage_inval);
+	target = pa >> (PAGE_SHIFT - DC_TAG_SHIFT);
+	cookie = ipi_dcache_page_inval(tl_ipi_spitfire_dcache_page_inval, pa);
+	for (addr = 0; addr < PCPU_GET(cache.dc_size);
+	    addr += PCPU_GET(cache.dc_linesize)) {
+		tag = ldxa(addr, ASI_DCACHE_TAG);
+		if (((tag >> DC_VALID_SHIFT) & DC_VALID_MASK) == 0)
+			continue;
+		tag &= DC_TAG_MASK << DC_TAG_SHIFT;
+		if (tag == target) {
+			PMAP_STATS_INC(spitfire_dcache_npage_inval_match);
+			stxa_sync(addr, ASI_DCACHE_TAG, tag);
+		}
+	}
+	ipi_wait(cookie);
+}
+
+/*
+ * Flush a physical page from the instruction cache.
+ */
+void
+spitfire_icache_page_inval(vm_paddr_t pa)
+{
+	register u_long tag __asm("%g1");
+	u_long target;
+	void *cookie;
+	u_long addr;
+
+	KASSERT((pa & PAGE_MASK) == 0, ("%s: pa not page aligned", __func__));
+	PMAP_STATS_INC(spitfire_icache_npage_inval);
+	target = pa >> (PAGE_SHIFT - IC_TAG_SHIFT);
+	cookie = ipi_icache_page_inval(tl_ipi_spitfire_icache_page_inval, pa);
+	for (addr = 0; addr < PCPU_GET(cache.ic_size);
+	    addr += PCPU_GET(cache.ic_linesize)) {
+		__asm __volatile("ldda [%1] %2, %%g0" /*, %g1 */
+		    : "=r" (tag) : "r" (addr), "n" (ASI_ICACHE_TAG));
+		if (((tag >> IC_VALID_SHIFT) & IC_VALID_MASK) == 0)
+			continue;
+		tag &= (u_long)IC_TAG_MASK << IC_TAG_SHIFT;
+		if (tag == target) {
+			PMAP_STATS_INC(spitfire_icache_npage_inval_match);
+			stxa_sync(addr, ASI_ICACHE_TAG, tag);
+		}
+	}
+	ipi_wait(cookie);
+}
+
+/*
+ * Flush all non-locked mappings from the TLBs.
+ */
+void
+spitfire_tlb_flush_nonlocked(void)
+{
+	u_int i;
+	u_int slot;
+
+	for (i = 0; i < SPITFIRE_TLB_ENTRIES; i++) {
+		slot = TLB_DAR_SLOT(TLB_DAR_T32, i);
+		if ((ldxa(slot, ASI_DTLB_DATA_ACCESS_REG) & TD_L) == 0)
+			stxa_sync(slot, ASI_DTLB_DATA_ACCESS_REG, 0);
+		if ((ldxa(slot, ASI_ITLB_DATA_ACCESS_REG) & TD_L) == 0)
+			stxa_sync(slot, ASI_ITLB_DATA_ACCESS_REG, 0);
+	}
+}
+
+/*
+ * Flush all user mappings from the TLBs.
+ */
+void
+spitfire_tlb_flush_user(void)
+{
+	u_long data;
+	u_long tag;
+	u_int i;
+	u_int slot;
+
+	for (i = 0; i < SPITFIRE_TLB_ENTRIES; i++) {
+		slot = TLB_DAR_SLOT(TLB_DAR_T32, i);
+		data = ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+		tag = ldxa(slot, ASI_DTLB_TAG_READ_REG);
+		if ((data & TD_V) != 0 && (data & TD_L) == 0 &&
+		    TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+			stxa_sync(slot, ASI_DTLB_DATA_ACCESS_REG, 0);
+		data = ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+		tag = ldxa(slot, ASI_ITLB_TAG_READ_REG);
+		if ((data & TD_V) != 0 && (data & TD_L) == 0 &&
+		    TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+			stxa_sync(slot, ASI_ITLB_DATA_ACCESS_REG, 0);
+	}
+}


Property changes on: trunk/sys/sparc64/sparc64/spitfire.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/ssm.c
===================================================================
--- trunk/sys/sparc64/sparc64/ssm.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/ssm.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,75 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/ssm.c 227848 2011-11-22 21:55:40Z marius $");
+
+/*
+ * Glue allowing devices beneath the scalable shared memory node to be
+ * treated like nexus(4) children
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <dev/ofw/ofw_bus.h>
+
+#include <machine/nexusvar.h>
+
+static device_probe_t ssm_probe;
+
+static device_method_t ssm_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ssm_probe),
+
+	/* Bus interface */
+
+	/* ofw_bus interface */
+
+	DEVMETHOD_END
+};
+
+static devclass_t ssm_devclass;
+
+DEFINE_CLASS_1(ssm, ssm_driver, ssm_methods, 1 /* no softc */, nexus_driver);
+EARLY_DRIVER_MODULE(ssm, nexus, ssm_driver, ssm_devclass, 0, 0, BUS_PASS_BUS);
+MODULE_DEPEND(ssm, nexus, 1, 1, 1);
+MODULE_VERSION(ssm, 1);
+
+static int
+ssm_probe(device_t dev)
+{
+
+	if (strcmp(ofw_bus_get_name(dev), "ssm") == 0) {
+		device_set_desc(dev, "Scalable Shared Memory");
+		return (BUS_PROBE_DEFAULT);
+	}
+	return (ENXIO);
+}


Property changes on: trunk/sys/sparc64/sparc64/ssm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/stack_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/stack_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/stack_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,89 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Antoine Brodin
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/stack_machdep.c 200272 2009-12-08 20:18:54Z marius $");
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/stack.h>
+#include <sys/systm.h>
+
+#include <machine/pcb.h>
+#include <machine/stack.h>
+#include <machine/vmparam.h>
+
+static void stack_capture(struct stack *st, struct frame *frame);
+
+static void
+stack_capture(struct stack *st, struct frame *frame)
+{
+	struct frame *fp;
+	vm_offset_t callpc;
+
+	stack_zero(st);
+	fp = frame;
+	for (;;) {
+		if (!INKERNEL((vm_offset_t)fp) ||
+		    !ALIGNED_POINTER(fp, uint64_t))
+                        break;
+		callpc = fp->fr_pc;
+		if (!INKERNEL(callpc))
+			break;
+		/* Don't bother traversing trap frames. */
+		if ((callpc > (uint64_t)tl_trap_begin &&
+		    callpc < (uint64_t)tl_trap_end) ||
+		    (callpc > (uint64_t)tl_text_begin &&
+		    callpc < (uint64_t)tl_text_end))
+			break;
+		if (stack_put(st, callpc) == -1)
+			break;
+		if (v9next_frame(fp) <= fp ||
+		    v9next_frame(fp) >= frame + KSTACK_PAGES * PAGE_SIZE)
+			break;
+		fp = v9next_frame(fp);
+	}
+}
+
+void
+stack_save_td(struct stack *st, struct thread *td)
+{
+
+	if (TD_IS_SWAPPED(td))
+		panic("stack_save_td: swapped");
+	if (TD_IS_RUNNING(td))
+		panic("stack_save_td: running");
+
+	stack_capture(st, (struct frame *)(td->td_pcb->pcb_sp + SPOFF));
+}
+
+void
+stack_save(struct stack *st)
+{
+
+	stack_capture(st, (struct frame *)__builtin_frame_address(1));
+}


Property changes on: trunk/sys/sparc64/sparc64/stack_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/support.S
===================================================================
--- trunk/sys/sparc64/sparc64/support.S	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/support.S	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,961 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/support.S 239941 2012-08-31 11:15:01Z marius $");
+
+#include <sys/errno.h>
+
+#include <machine/asi.h>
+#include <machine/asmacros.h>
+#include <machine/fsr.h>
+#include <machine/intr_machdep.h>
+#include <machine/pcb.h>
+#include <machine/pstate.h>
+#include <machine/wstate.h>
+
+#include "assym.s"
+
+	.register %g2, #ignore
+	.register %g3, #ignore
+	.register %g6, #ignore
+
+/*
+ * Common code for copy routines.
+ *
+ * We use large macros to generate functions for each of the copy routines.
+ * This allows the load and store instructions to be generated for the right
+ * operation, asi or not.  It is possible to write an asi independent function
+ * but this would require 2 expensive wrs in the main loop to switch %asi.
+ * It would also screw up profiling (if we ever get it), but may save some I$.
+ * We assume that either one of dasi and sasi is empty, or that they are both
+ * the same (empty or non-empty).  It is up to the caller to set %asi.
+ */
+
+/*
+ * ASI independent implementation of copystr(9).
+ * Used to implement copyinstr() and copystr().
+ *
+ * Return value is in %g1.
+ */
+#define	_COPYSTR(src, dst, len, done, sa, sasi, da, dasi) \
+	brz	len, 4f ; \
+	 mov	src, %g2 ; \
+1:	deccc	1, len ; \
+	bl,a,pn	%xcc, 3f ; \
+	 nop ; \
+	LD(ub, sa) [src] sasi, %g1 ; \
+	ST(b, da) %g1, [dst] dasi ; \
+	brz,pn	%g1, 3f ; \
+	 inc	src ; \
+	ba	%xcc, 1b ; \
+	 inc	dst ; \
+2:	mov	ENAMETOOLONG, %g1 ; \
+3:	sub	src, %g2, %g2 ; \
+	brnz,a	done, 4f ; \
+	 stx	%g2, [done] ; \
+4:
+
+/*
+ * ASI independent implementation of memset(3).
+ * Used to implement bzero(), memset() and aszero().
+ *
+ * If the pattern is non-zero, duplicate it to fill 64 bits.
+ * Store bytes until dst is 8-byte aligned, then store 8 bytes.
+ * It has yet to be determined how much unrolling is beneficial.
+ * Could also read and compare before writing to minimize snoop traffic.
+ *
+ * XXX bzero() should be implemented as
+ * #define bzero(dst, len) (void)memset((dst), 0, (len))
+ * if at all.
+ */
+#define	_MEMSET(dst, pat, len, da, dasi) \
+	brlez,pn len, 5f ; \
+	 and	pat, 0xff, pat ; \
+	brz,pt	pat, 1f ; \
+	 sllx	pat, 8, %g1 ; \
+	or	pat, %g1, pat ; \
+	sllx	pat, 16, %g1 ; \
+	or	pat, %g1, pat ; \
+	sllx	pat, 32, %g1 ; \
+	or	pat, %g1, pat ; \
+	.align 16 ; \
+1:	deccc	1, len ; \
+	bl,pn	%xcc, 5f ; \
+	 btst	7, dst ; \
+	bz,a,pt	%xcc, 2f ; \
+	 inc	1, len ; \
+	ST(b, da) pat, [dst] dasi ; \
+	ba	%xcc, 1b ; \
+	 inc	dst ; \
+	.align 16 ; \
+2:	deccc	32, len ; \
+	bl,a,pn	%xcc, 3f ; \
+	 inc	32, len ; \
+	ST(x, da) pat, [dst] dasi ; \
+	ST(x, da) pat, [dst + 8] dasi ; \
+	ST(x, da) pat, [dst + 16] dasi ; \
+	ST(x, da) pat, [dst + 24] dasi ; \
+	ba	%xcc, 2b ; \
+	 inc	32, dst ; \
+	.align 16 ; \
+3:	deccc	8, len ; \
+	bl,a,pn	%xcc, 4f ; \
+	 inc	8, len ; \
+	ST(x, da) pat, [dst] dasi ; \
+	ba	%xcc, 3b ; \
+	 inc	8, dst ; \
+	.align 16 ; \
+4:	deccc	1, len ; \
+	bl,a,pn	%xcc, 5f ; \
+	 nop ; \
+	ST(b, da) pat, [dst] dasi ; \
+	ba	%xcc, 4b ; \
+	 inc	1, dst ; \
+5:
+
+/*
+ * ASI independent implementation of memcpy(3).
+ * Used to implement bcopy(), copyin(), copyout(), memcpy(), ascopy(),
+ * ascopyfrom() and ascopyto().
+ *
+ * Transfer bytes until dst is 8-byte aligned.  If src is then also 8 byte
+ * aligned, transfer 8 bytes, otherwise finish with bytes.  The unaligned
+ * case could be optimized, but it is expected that this is the uncommon
+ * case and of questionable value.  The code to do so is also rather large
+ * and ugly.  It has yet to be determined how much unrolling is beneficial.
+ *
+ * XXX bcopy() must also check for overlap.  This is stupid.
+ * XXX bcopy() should be implemented as
+ * #define bcopy(src, dst, len) (void)memcpy((dst), (src), (len))
+ * if at all.
+ */
+#define	_MEMCPY(dst, src, len, da, dasi, sa, sasi) \
+1:	deccc	1, len ; \
+	bl,pn	%xcc, 6f ; \
+	 btst	7, dst ; \
+	bz,a,pt	%xcc, 2f ; \
+	 inc	1, len ; \
+	LD(ub, sa) [src] sasi, %g1 ; \
+	ST(b, da) %g1, [dst] dasi ; \
+	inc	1, src ; \
+	ba	%xcc, 1b ; \
+	 inc	1, dst ; \
+	.align 16 ; \
+2:	btst	7, src ; \
+	bz,a,pt	%xcc, 3f ; \
+	 nop ; \
+	ba,a	%xcc, 5f ; \
+	.align 16 ; \
+3:	deccc	32, len ; \
+	bl,a,pn	%xcc, 4f ; \
+	 inc	32, len ; \
+	LD(x, sa) [src] sasi, %g1 ; \
+	LD(x, sa) [src + 8] sasi, %g2 ; \
+	LD(x, sa) [src + 16] sasi, %g3 ; \
+	LD(x, sa) [src + 24] sasi, %g4 ; \
+	ST(x, da) %g1, [dst] dasi ; \
+	ST(x, da) %g2, [dst + 8] dasi ; \
+	ST(x, da) %g3, [dst + 16] dasi ; \
+	ST(x, da) %g4, [dst + 24] dasi ; \
+	inc	32, src ; \
+	ba	%xcc, 3b ; \
+	 inc	32, dst ; \
+	.align 16 ; \
+4:	deccc	8, len ; \
+	bl,a,pn	%xcc, 5f ; \
+	 inc	8, len ; \
+	LD(x, sa) [src] sasi, %g1 ; \
+	ST(x, da) %g1, [dst] dasi ; \
+	inc	8, src ; \
+	ba	%xcc, 4b ; \
+	 inc	8, dst ; \
+	.align 16 ; \
+5:	deccc	1, len ; \
+	bl,a,pn	%xcc, 6f ; \
+	 nop ; \
+	LD(ub, sa) [src] sasi, %g1 ; \
+	ST(b, da) %g1, [dst] dasi ; \
+	inc	src ; \
+	ba	%xcc, 5b ; \
+	 inc	dst ; \
+6:
+
+/*
+ * void ascopy(u_long asi, vm_offset_t src, vm_offset_t dst, size_t len)
+ */
+ENTRY(ascopy)
+	wr	%o0, 0, %asi
+	_MEMCPY(%o2, %o1, %o3, a, %asi, a, %asi)
+	retl
+	 nop
+END(ascopy)
+
+/*
+ * void ascopyfrom(u_long sasi, vm_offset_t src, caddr_t dst, size_t len)
+ */
+ENTRY(ascopyfrom)
+	wr	%o0, 0, %asi
+	_MEMCPY(%o2, %o1, %o3, EMPTY, EMPTY, a, %asi)
+	retl
+	 nop
+END(ascopyfrom)
+
+/*
+ * void ascopyto(caddr_t src, u_long dasi, vm_offset_t dst, size_t len)
+ */
+ENTRY(ascopyto)
+	wr	%o1, 0, %asi
+	_MEMCPY(%o2, %o0, %o3, a, %asi, EMPTY, EMPTY)
+	retl
+	 nop
+END(ascopyto)
+
+/*
+ * void aszero(u_long asi, vm_offset_t pa, size_t len)
+ */
+ENTRY(aszero)
+	wr	%o0, 0, %asi
+	_MEMSET(%o1, %g0, %o2, a, %asi)
+	retl
+	 nop
+END(aszero)
+
+/*
+ * int bcmp(const void *b1, const void *b2, size_t len)
+ */
+ENTRY(bcmp)
+	brz,pn	%o2, 2f
+	 clr	%o3
+1:	ldub	[%o0 + %o3], %o4
+	ldub	[%o1 + %o3], %o5
+	cmp	%o4, %o5
+	bne,pn	%xcc, 2f
+	 inc	%o3
+	deccc	%o2
+	bne,pt	%xcc, 1b
+	 nop
+2:	retl
+	 mov	%o2, %o0
+END(bcmp)
+
+/*
+ * void bcopy(const void *src, void *dst, size_t len)
+ */
+ENTRY(bcopy)
+	/*
+	 * Check for overlap, and copy backwards if so.
+	 */
+	sub	%o1, %o0, %g1
+	cmp	%g1, %o2
+	bgeu,a,pt %xcc, 3f
+	 nop
+
+	/*
+	 * Copy backwards.
+	 */
+	add	%o0, %o2, %o0
+	add	%o1, %o2, %o1
+1:	deccc	1, %o2
+	bl,a,pn	%xcc, 2f
+	 nop
+	dec	1, %o0
+	ldub	[%o0], %g1
+	dec	1, %o1
+	ba	%xcc, 1b
+	 stb	%g1, [%o1]
+2:	retl
+	 nop
+
+	/*
+	 * Do the fast version.
+	 */
+3:	_MEMCPY(%o1, %o0, %o2, EMPTY, EMPTY, EMPTY, EMPTY)
+	retl
+	 nop
+END(bcopy)
+
+/*
+ * void bzero(void *b, size_t len)
+ */
+ENTRY(bzero)
+	_MEMSET(%o0, %g0, %o1, EMPTY, EMPTY)
+	retl
+	 nop
+END(bzero)
+
+/*
+ * int copystr(const void *src, void *dst, size_t len, size_t *done)
+ */
+ENTRY(copystr)
+	_COPYSTR(%o0, %o1, %o2, %o3, EMPTY, EMPTY, EMPTY, EMPTY)
+	retl
+	 mov	%g1, %o0
+END(copystr)
+
+/*
+ * void *memcpy(void *dst, const void *src, size_t len)
+ */
+ENTRY(memcpy)
+	mov	%o0, %o3
+	_MEMCPY(%o3, %o1, %o2, EMPTY, EMPTY, EMPTY, EMPTY)
+	retl
+	 nop
+END(memcpy)
+
+/*
+ * void *memset(void *b, int c, size_t len)
+ */
+ENTRY(memset)
+	mov	%o0, %o3
+	_MEMSET(%o3, %o1, %o2, EMPTY, EMPTY)
+	retl
+	 nop
+END(memset)
+
+	.globl	copy_nofault_begin
+copy_nofault_begin:
+	nop
+
+/*
+ * int copyin(const void *uaddr, void *kaddr, size_t len)
+ */
+ENTRY(copyin)
+	wr	%g0, ASI_AIUP, %asi
+	_MEMCPY(%o1, %o0, %o2, EMPTY, EMPTY, a, %asi)
+	retl
+	 clr	%o0
+END(copyin)
+
+/*
+ * int copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done)
+ */
+ENTRY(copyinstr)
+	wr	%g0, ASI_AIUP, %asi
+	_COPYSTR(%o0, %o1, %o2, %o3, a, %asi, EMPTY, EMPTY)
+	retl
+	 mov	%g1, %o0
+END(copyinstr)
+
+/*
+ * int copyout(const void *kaddr, void *uaddr, size_t len)
+ */
+ENTRY(copyout)
+	wr	%g0, ASI_AIUP, %asi
+	_MEMCPY(%o1, %o0, %o2, a, %asi, EMPTY, EMPTY)
+	retl
+	 clr	%o0
+END(copyout)
+
+	.globl	copy_nofault_end
+copy_nofault_end:
+	nop
+
+ENTRY(copy_fault)
+	retl
+	 mov	EFAULT, %o0
+END(copy_fault)
+
+	.globl	fs_nofault_begin
+fs_nofault_begin:
+	nop
+
+/*
+ * Chatty aliases for fetch, store functions.
+ */
+	.globl	fubyte, fusword, fuword, subyte, susword, suword
+	.set	fubyte, fuword8
+	.set	fusword, fuword16
+	.set	fuword, fuword64
+	.set	subyte, suword8
+	.set	susword, suword16
+	.set	suword, suword64
+
+	.globl	casuword32, casuword, fuptr, suptr
+	.set	casuword, casuword64
+	.set	fuptr, fuword64
+	.set	suptr, suword64
+
+/*
+ * int32_t casuword32(volatile int32_t *p, int32_t e, int32_t s)
+ */
+ENTRY(casuword32)
+	casa	[%o0] ASI_AIUP, %o1, %o2
+	retl
+	 mov	%o2, %o0
+END(casuword32)
+
+/*
+ * int64_t casuword64(volatile int64_t *p, int64_t e, int64_t s)
+ */
+ENTRY(casuword64)
+	casxa	[%o0] ASI_AIUP, %o1, %o2
+	retl
+	 mov	%o2, %o0
+END(casuword64)
+
+/*
+ * int fuword8(const void *base)
+ */
+ENTRY(fuword8)
+	retl
+	 lduba	[%o0] ASI_AIUP, %o0
+END(fuword8)
+
+/*
+ * int fuword16(const void *base)
+ */
+ENTRY(fuword16)
+	retl
+	 lduha	[%o0] ASI_AIUP, %o0
+END(fuword16)
+
+/*
+ * int32_t fuword32(const void *base)
+ */
+ENTRY(fuword32)
+	retl
+	 lduwa	[%o0] ASI_AIUP, %o0
+END(fuword32)
+
+/*
+ * int64_t fuword64(const void *base)
+ */
+ENTRY(fuword64)
+	retl
+	 ldxa	[%o0] ASI_AIUP, %o0
+END(fuword64)
+
+/*
+ * int suword8(const void *base, int word)
+ */
+ENTRY(suword8)
+	stba	%o1, [%o0] ASI_AIUP
+	retl
+	 clr	%o0
+END(suword8)
+
+/*
+ * int suword16(const void *base, int word)
+ */
+ENTRY(suword16)
+	stha	%o1, [%o0] ASI_AIUP
+	retl
+	 clr	%o0
+END(suword16)
+
+/*
+ * int suword32(const void *base, int32_t word)
+ */
+ENTRY(suword32)
+	stwa	%o1, [%o0] ASI_AIUP
+	retl
+	 clr	%o0
+END(suword32)
+
+/*
+ * int suword64(const void *base, int64_t word)
+ */
+ENTRY(suword64)
+	stxa	%o1, [%o0] ASI_AIUP
+	retl
+	 clr	%o0
+END(suword64)
+
+	.globl	fs_nofault_intr_begin
+fs_nofault_intr_begin:
+	nop
+
+/*
+ * int fuswintr(const void *base)
+ */
+ENTRY(fuswintr)
+	retl
+	 lduha	[%o0] ASI_AIUP, %o0
+END(fuswintr)
+
+/*
+ * int suswintr(const void *base, int word)
+ */
+ENTRY(suswintr)
+	stha	%o1, [%o0] ASI_AIUP
+	retl
+	 clr	%o0
+END(suswintr)
+
+	.globl	fs_nofault_intr_end
+fs_nofault_intr_end:
+	nop
+
+	.globl	fs_nofault_end
+fs_nofault_end:
+	nop
+
+ENTRY(fs_fault)
+	retl
+	 mov	-1, %o0
+END(fsfault)
+
+	.globl	fas_nofault_begin
+fas_nofault_begin:
+
+/*
+ * int fasword8(u_long asi, uint64_t addr, uint8_t *val)
+ */
+ENTRY(fasword8)
+	wr	%o0, 0, %asi
+	membar	#Sync
+	lduba	[%o1] %asi, %o3
+	membar	#Sync
+	stb	%o3, [%o2]
+	retl
+	 clr	%o0
+END(fasword8)
+
+/*
+ * int fasword16(u_long asi, uint64_t addr, uint16_t *val)
+ */
+ENTRY(fasword16)
+	wr	%o0, 0, %asi
+	membar	#Sync
+	lduha	[%o1] %asi, %o3
+	membar	#Sync
+	sth	%o3, [%o2]
+	retl
+	 clr	%o0
+END(fasword16)
+
+/*
+ * int fasword32(u_long asi, uint64_t addr, uint32_t *val)
+ */
+ENTRY(fasword32)
+	wr	%o0, 0, %asi
+	membar	#Sync
+	lduwa	[%o1] %asi, %o3
+	membar	#Sync
+	stw	%o3, [%o2]
+	retl
+	 clr	%o0
+END(fasword32)
+
+	.globl	fas_nofault_end
+fas_nofault_end:
+	nop
+
+	.globl	fas_fault
+ENTRY(fas_fault)
+	retl
+	 mov	-1, %o0
+END(fas_fault)
+
+	.globl	fpu_fault_begin
+fpu_fault_begin:
+	nop
+
+/*
+ * void spitfire_block_copy(void *src, void *dst, size_t len)
+ */
+ENTRY(spitfire_block_copy)
+	rdpr	%pstate, %o3
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	wr	%g0, ASI_BLK_S, %asi
+	wr	%g0, FPRS_FEF, %fprs
+
+	sub	PCB_REG, TF_SIZEOF, %o4
+	ldx	[%o4 + TF_FPRS], %o5
+	andcc	%o5, FPRS_FEF, %g0
+	bz,a,pt	%xcc, 1f
+	 nop
+	stda	%f0, [PCB_REG + PCB_UFP + (0 * VIS_BLOCKSIZE)] %asi
+	stda	%f16, [PCB_REG + PCB_UFP + (1 * VIS_BLOCKSIZE)] %asi
+	stda	%f32, [PCB_REG + PCB_UFP + (2 * VIS_BLOCKSIZE)] %asi
+	stda	%f48, [PCB_REG + PCB_UFP + (3 * VIS_BLOCKSIZE)] %asi
+	membar	#Sync
+
+	andn	%o5, FPRS_FEF, %o5
+	stx	%o5, [%o4 + TF_FPRS]
+	ldx	[PCB_REG + PCB_FLAGS], %o4
+	or	%o4, PCB_FEF, %o4
+	stx	%o4, [PCB_REG + PCB_FLAGS]
+
+1:	wrpr	%o3, 0, %pstate
+
+	ldda	[%o0] %asi, %f0
+	add	%o0, VIS_BLOCKSIZE, %o0
+	sub	%o2, VIS_BLOCKSIZE, %o2
+
+2:	ldda	[%o0] %asi, %f16
+	fsrc1	%f0, %f32
+	fsrc1	%f2, %f34
+	fsrc1	%f4, %f36
+	fsrc1	%f6, %f38
+	fsrc1	%f8, %f40
+	fsrc1	%f10, %f42
+	fsrc1	%f12, %f44
+	fsrc1	%f14, %f46
+	stda	%f32, [%o1] %asi
+	add	%o0, VIS_BLOCKSIZE, %o0
+	subcc	%o2, VIS_BLOCKSIZE, %o2
+	bz,pn	%xcc, 3f
+	 add	%o1, VIS_BLOCKSIZE, %o1
+	ldda	[%o0] %asi, %f0
+	fsrc1	%f16, %f32
+	fsrc1	%f18, %f34
+	fsrc1	%f20, %f36
+	fsrc1	%f22, %f38
+	fsrc1	%f24, %f40
+	fsrc1	%f26, %f42
+	fsrc1	%f28, %f44
+	fsrc1	%f30, %f46
+	stda	%f32, [%o1] %asi
+	add	%o0, VIS_BLOCKSIZE, %o0
+	sub	%o2, VIS_BLOCKSIZE, %o2
+	ba,pt	%xcc, 2b
+	 add	%o1, VIS_BLOCKSIZE, %o1
+
+3:	membar	#Sync
+
+	stda	%f16, [%o1] %asi
+	membar	#Sync
+
+	retl
+	 wr	%g0, 0, %fprs
+END(spitfire_block_copy)
+
+/*
+ * void zeus_block_copy(void *src, void *dst, size_t len)
+ */
+ENTRY(zeus_block_copy)
+	prefetch [%o0 + (0 * VIS_BLOCKSIZE)], 0
+
+	rdpr	%pstate, %o3
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	wr	%g0, ASI_BLK_S, %asi
+	wr	%g0, FPRS_FEF, %fprs
+
+	sub	PCB_REG, TF_SIZEOF, %o4
+	ldx	[%o4 + TF_FPRS], %o5
+	andcc	%o5, FPRS_FEF, %g0
+	bz,a,pt	%xcc, 1f
+	 nop
+	stda	%f0, [PCB_REG + PCB_UFP + (0 * VIS_BLOCKSIZE)] %asi
+	stda	%f16, [PCB_REG + PCB_UFP + (1 * VIS_BLOCKSIZE)] %asi
+	stda	%f32, [PCB_REG + PCB_UFP + (2 * VIS_BLOCKSIZE)] %asi
+	stda	%f48, [PCB_REG + PCB_UFP + (3 * VIS_BLOCKSIZE)] %asi
+	membar	#Sync
+
+	andn	%o5, FPRS_FEF, %o5
+	stx	%o5, [%o4 + TF_FPRS]
+	ldx	[PCB_REG + PCB_FLAGS], %o4
+	or	%o4, PCB_FEF, %o4
+	stx	%o4, [PCB_REG + PCB_FLAGS]
+
+1:	wrpr	%o3, 0, %pstate
+
+	ldd	[%o0 + (0 * 8)], %f0
+	prefetch [%o0 + (1 * VIS_BLOCKSIZE)], 0
+	ldd	[%o0 + (1 * 8)], %f2
+	prefetch [%o0 + (2 * VIS_BLOCKSIZE)], 0
+	fmovd	%f0, %f32
+	ldd	[%o0 + (2 * 8)], %f4
+	prefetch [%o0 + (3 * VIS_BLOCKSIZE)], 0
+	fmovd	%f2, %f34
+	ldd	[%o0 + (3 * 8)], %f6
+	prefetch [%o0 + (4 * VIS_BLOCKSIZE)], 1
+	fmovd	%f4, %f36
+	ldd	[%o0 + (4 * 8)], %f8
+	prefetch [%o0 + (8 * VIS_BLOCKSIZE)], 1
+	fmovd	%f6, %f38
+	ldd	[%o0 + (5 * 8)], %f10
+	prefetch [%o0 + (12 * VIS_BLOCKSIZE)], 1
+	fmovd	%f8, %f40
+	ldd	[%o0 + (6 * 8)], %f12
+	prefetch [%o0 + (16 * VIS_BLOCKSIZE)], 1
+	fmovd	%f10, %f42
+	ldd	[%o0 + (7 * 8)], %f14
+	ldd	[%o0 + (8 * 8)], %f0
+	sub	%o2, VIS_BLOCKSIZE, %o2
+	add	%o0, VIS_BLOCKSIZE, %o0
+	prefetch [%o0 + (19 * VIS_BLOCKSIZE)], 1
+	ba,pt	%xcc, 2f
+	 prefetch [%o0 + (23 * VIS_BLOCKSIZE)], 1
+	.align	32
+
+2:	ldd	[%o0 + (1 * 8)], %f2
+	fmovd	%f12, %f44
+	ldd	[%o0 + (2 * 8)], %f4
+	fmovd	%f14, %f46
+	stda	%f32, [%o1] %asi
+	ldd	[%o0 + (3 * 8)], %f6
+	fmovd	%f0, %f32
+	ldd	[%o0 + (4 * 8)], %f8
+	fmovd	%f2, %f34
+	ldd	[%o0 + (5 * 8)], %f10
+	fmovd	%f4, %f36
+	ldd	[%o0 + (6 * 8)], %f12
+	fmovd	%f6, %f38
+	ldd	[%o0 + (7 * 8)], %f14
+	fmovd	%f8, %f40
+	ldd	[%o0 + (8 * 8)], %f0
+	fmovd	%f10, %f42
+	sub	%o2, VIS_BLOCKSIZE, %o2
+	prefetch [%o0 + (3 * VIS_BLOCKSIZE)], 0
+	add	%o1, VIS_BLOCKSIZE, %o1
+	prefetch [%o0 + (24 * VIS_BLOCKSIZE)], 1
+	add	%o0, VIS_BLOCKSIZE, %o0
+	cmp	%o2, VIS_BLOCKSIZE + 8
+	bgu,pt	%xcc, 2b
+	 prefetch [%o0 + (12 * VIS_BLOCKSIZE)], 1
+	ldd	[%o0 + (1 * 8)], %f2
+	fsrc1	%f12, %f44
+	ldd	[%o0 + (2 * 8)], %f4
+	fsrc1	%f14, %f46
+	stda	%f32, [%o1] %asi
+	ldd	[%o0 + (3 * 8)], %f6
+	fsrc1	%f0, %f32
+	ldd	[%o0 + (4 * 8)], %f8
+	fsrc1	%f2, %f34
+	ldd	[%o0 + (5 * 8)], %f10
+	fsrc1	%f4, %f36
+	ldd	[%o0 + (6 * 8)], %f12
+	fsrc1	%f6, %f38
+	ldd	[%o0 + (7 * 8)], %f14
+	fsrc1	%f8, %f40
+	add	%o1, VIS_BLOCKSIZE, %o1
+	fsrc1	%f10, %f42
+	fsrc1	%f12, %f44
+	fsrc1	%f14, %f46
+	stda	%f32, [%o1] %asi
+	membar	#Sync
+
+	retl
+	 wr	%g0, 0, %fprs
+END(zeus_block_copy)
+
+/*
+ * void spitfire_block_zero(void *dst, size_t len)
+ * void zeus_block_zero(void *dst, size_t len)
+ */
+ALTENTRY(zeus_block_zero)
+ENTRY(spitfire_block_zero)
+	rdpr	%pstate, %o3
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+
+	wr	%g0, ASI_BLK_S, %asi
+	wr	%g0, FPRS_FEF, %fprs
+
+	sub	PCB_REG, TF_SIZEOF, %o4
+	ldx	[%o4 + TF_FPRS], %o5
+	andcc	%o5, FPRS_FEF, %g0
+	bz,a,pt	%xcc, 1f
+	 nop
+	stda	%f0, [PCB_REG + PCB_UFP + (0 * VIS_BLOCKSIZE)] %asi
+	stda	%f16, [PCB_REG + PCB_UFP + (1 * VIS_BLOCKSIZE)] %asi
+	stda	%f32, [PCB_REG + PCB_UFP + (2 * VIS_BLOCKSIZE)] %asi
+	stda	%f48, [PCB_REG + PCB_UFP + (3 * VIS_BLOCKSIZE)] %asi
+	membar	#Sync
+
+	andn	%o5, FPRS_FEF, %o5
+	stx	%o5, [%o4 + TF_FPRS]
+	ldx	[PCB_REG + PCB_FLAGS], %o4
+	or	%o4, PCB_FEF, %o4
+	stx	%o4, [PCB_REG + PCB_FLAGS]
+
+1:	wrpr	%o3, 0, %pstate
+
+	fzero	%f0
+	fzero	%f2
+	fzero	%f4
+	fzero	%f6
+	fzero	%f8
+	fzero	%f10
+	fzero	%f12
+	fzero	%f14
+
+1:	stda	%f0, [%o0 + (0 * VIS_BLOCKSIZE)] %asi
+	stda	%f0, [%o0 + (1 * VIS_BLOCKSIZE)] %asi
+	stda	%f0, [%o0 + (2 * VIS_BLOCKSIZE)] %asi
+	stda	%f0, [%o0 + (3 * VIS_BLOCKSIZE)] %asi
+	sub	%o1, (4 * VIS_BLOCKSIZE), %o1
+	brnz,pt	%o1, 1b
+	 add	%o0, (4 * VIS_BLOCKSIZE), %o0
+	membar	#Sync
+
+	retl
+	 wr	%g0, 0, %fprs
+END(spitfire_block_zero)
+
+	.globl	fpu_fault_end
+fpu_fault_end:
+	nop
+
+	.globl	fpu_fault_size
+	.set	fpu_fault_size, fpu_fault_end - fpu_fault_begin
+
+ENTRY(longjmp)
+	set	1, %g3
+	movrz	%o1, %o1, %g3
+	mov	%o0, %g1
+	ldx	[%g1 + _JB_FP], %g2
+1:	cmp	%fp, %g2
+	bl,a,pt	%xcc, 1b
+	 restore
+	bne,pn	%xcc, 2f
+	 ldx	[%g1 + _JB_SP], %o2
+	cmp	%o2, %sp
+	blt,pn	%xcc, 2f
+	 movge	%xcc, %o2, %sp
+	ldx	[%g1 + _JB_PC], %o7
+	retl
+	 mov	%g3, %o0
+2:	PANIC("longjmp botch", %l1)
+END(longjmp)
+
+ENTRY(setjmp)
+	stx	%sp, [%o0 + _JB_SP]
+	stx	%o7, [%o0 + _JB_PC]
+	stx	%fp, [%o0 + _JB_FP]
+	retl
+	 clr	%o0
+END(setjmp)
+
+/*
+ * void ofw_entry(cell_t args[])
+ */
+ENTRY(ofw_entry)
+	save	%sp, -CCFSZ, %sp
+	SET(ofw_vec, %l7, %l6)
+	ldx	[%l6], %l6
+	rdpr	%pstate, %l7
+	andn	%l7, PSTATE_AM | PSTATE_IE, %l5
+	wrpr	%l5, 0, %pstate
+	SET(tba_taken_over, %l5, %l4)
+	brz,pn	%l4, 1f
+	 rdpr	%wstate, %l5
+	andn	%l5, WSTATE_PROM_MASK, %l3
+	wrpr	%l3, WSTATE_PROM_KMIX, %wstate
+1:	call	%l6
+	 mov	%i0, %o0
+	brz,pn	%l4, 1f
+	 nop
+	wrpr	%g0, %l5, %wstate
+1:	wrpr	%l7, 0, %pstate
+	ret
+	 restore %o0, %g0, %o0
+END(ofw_entry)
+
+/*
+ * void ofw_exit(cell_t args[])
+ */
+ENTRY(ofw_exit)
+	save	%sp, -CCFSZ, %sp
+	flushw
+	SET(ofw_tba, %l7, %l5)
+	ldx	[%l5], %l5
+	rdpr	%pstate, %l7
+	andn	%l7, PSTATE_AM | PSTATE_IE, %l7
+	wrpr	%l7, 0, %pstate
+	rdpr	%wstate, %l7
+	andn	%l7, WSTATE_PROM_MASK, %l7
+	wrpr	%l7, WSTATE_PROM_KMIX, %wstate
+	wrpr	%l5, 0, %tba			! restore the OFW trap table
+	SET(ofw_vec, %l7, %l6)
+	ldx	[%l6], %l6
+	SET(kstack0 + KSTACK_PAGES * PAGE_SIZE - PCB_SIZEOF, %l7, %l0)
+	sub	%l0, SPOFF, %fp			! setup a stack in a locked page
+	sub	%l0, SPOFF + CCFSZ, %sp
+	mov	AA_DMMU_PCXR, %l3		! force primary DMMU context 0
+	sethi	%hi(KERNBASE), %l5
+	stxa	%g0, [%l3] ASI_DMMU
+	flush	%l5
+	wrpr	%g0, 0, %tl			! force trap level 0
+	call	%l6
+	 mov	%i0, %o0
+	! never to return
+END(ofw_exit)
+
+#ifdef GPROF
+
+ENTRY(user)
+	nop
+
+ENTRY(btrap)
+	nop
+
+ENTRY(etrap)
+	nop
+
+ENTRY(bintr)
+	nop
+
+ENTRY(eintr)
+	nop
+
+/*
+ * XXX including sys/gmon.h in genassym.c is not possible due to uintfptr_t
+ * badness.
+ */
+#define	GM_STATE	0x0
+#define	GMON_PROF_OFF	3
+#define	GMON_PROF_HIRES	4
+
+	.globl	_mcount
+	.set	_mcount, __cyg_profile_func_enter
+
+ENTRY(__cyg_profile_func_enter)
+	SET(_gmonparam, %o3, %o2)
+	lduw	[%o2 + GM_STATE], %o3
+	cmp	%o3, GMON_PROF_OFF
+	be,a,pn %icc, 1f
+	 nop
+	SET(mcount, %o3, %o2)
+	jmpl	%o2, %g0
+	 nop
+1:	retl
+	 nop
+END(__cyg_profile_func_enter)
+
+#ifdef GUPROF
+
+ENTRY(__cyg_profile_func_exit)
+	SET(_gmonparam, %o3, %o2)
+	lduw	[%o2 + GM_STATE], %o3
+	cmp	%o3, GMON_PROF_HIRES
+	be,a,pn %icc, 1f
+	 nop
+	SET(mexitcount, %o3, %o2)
+	jmpl	%o2, %g0
+	 nop
+1:	retl
+	 nop
+END(__cyg_profile_func_exit)
+
+#endif /* GUPROF */
+
+#endif /* GPROF */


Property changes on: trunk/sys/sparc64/sparc64/support.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/swtch.S
===================================================================
--- trunk/sys/sparc64/sparc64/swtch.S	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/swtch.S	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,345 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * Copyright (c) 2011 Marius Strobl <marius at 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, 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.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/swtch.S 293853 2016-01-13 21:38:52Z marius $");
+
+#include <machine/asmacros.h>
+#include <machine/asi.h>
+#include <machine/fsr.h>
+#include <machine/ktr.h>
+#include <machine/pcb.h>
+#include <machine/tstate.h>
+
+#include "assym.s"
+#include "opt_sched.h"
+
+	.register	%g2, #ignore
+	.register	%g3, #ignore
+
+/*
+ * void cpu_throw(struct thread *old, struct thread *new)
+ */
+ENTRY(cpu_throw)
+	save	%sp, -CCFSZ, %sp
+	flushw
+	ba	%xcc, .Lsw1
+	 mov	%g0, %i2
+END(cpu_throw)
+
+/*
+ * void cpu_switch(struct thread *old, struct thread *new, struct mtx *mtx)
+ */
+ENTRY(cpu_switch)
+	save	%sp, -CCFSZ, %sp
+
+	/*
+	 * If the current thread was using floating point in the kernel, save
+	 * its context.  The userland floating point context has already been
+	 * saved in that case.
+	 */
+	rd	%fprs, %l2
+	andcc	%l2, FPRS_FEF, %g0
+	bz,a,pt	%xcc, 1f
+	 nop
+	call	savefpctx
+	 add	PCB_REG, PCB_KFP, %o0
+	ba,a,pt	%xcc, 2f
+	 nop
+
+	/*
+	 * If the current thread was using floating point in userland, save
+	 * its context.
+	 */
+1:	sub	PCB_REG, TF_SIZEOF, %l2
+	ldx	[%l2 + TF_FPRS], %l3
+	andcc	%l3, FPRS_FEF, %g0
+	bz,a,pt	%xcc, 2f
+	 nop
+	call	savefpctx
+	 add	PCB_REG, PCB_UFP, %o0
+	andn	%l3, FPRS_FEF, %l3
+	stx	%l3, [%l2 + TF_FPRS]
+
+	ldx	[PCB_REG + PCB_FLAGS], %l3
+	or	%l3, PCB_FEF, %l3
+	stx	%l3, [PCB_REG + PCB_FLAGS]
+
+	/*
+	 * Flush the windows out to the stack and save the current frame
+	 * pointer and program counter.
+	 */
+2:	flushw
+	wrpr	%g0, 0, %cleanwin
+	stx	%fp, [PCB_REG + PCB_SP]
+	stx	%i7, [PCB_REG + PCB_PC]
+
+	/*
+	 * Load the new thread's frame pointer and program counter, and set
+	 * the current thread and pcb.
+	 */
+.Lsw1:
+#if KTR_COMPILE & KTR_PROC
+	CATR(KTR_PROC, "cpu_switch: new td=%p pc=%#lx fp=%#lx"
+	    , %g1, %g2, %g3, 8, 9, 10)
+	stx	%i1, [%g1 + KTR_PARM1]
+	ldx	[%i1 + TD_PCB], %g2
+	ldx	[%g2 + PCB_PC], %g3
+	stx	%g3, [%g1 + KTR_PARM2]
+	ldx	[%g2 + PCB_SP], %g3
+	stx	%g3, [%g1 + KTR_PARM3]
+10:
+#endif
+	ldx	[%i1 + TD_PCB], %l0
+
+	stx	%i1, [PCPU(CURTHREAD)]
+	stx	%l0, [PCPU(CURPCB)]
+
+	wrpr	%g0, PSTATE_NORMAL, %pstate
+	mov	%l0, PCB_REG
+	wrpr	%g0, PSTATE_ALT, %pstate
+	mov	%l0, PCB_REG
+	wrpr	%g0, PSTATE_KERNEL, %pstate
+
+	ldx	[PCB_REG + PCB_SP], %fp
+	ldx	[PCB_REG + PCB_PC], %i7
+	sub	%fp, CCFSZ, %sp
+
+	/*
+	 * Point to the pmaps of the new process, and of the last non-kernel
+	 * process to run.
+	 */
+	ldx	[%i1 + TD_PROC], %l1
+	ldx	[PCPU(PMAP)], %l2
+	ldx	[%l1 + P_VMSPACE], %i5
+	add	%i5, VM_PMAP, %l1
+
+#if KTR_COMPILE & KTR_PROC
+	CATR(KTR_PROC, "cpu_switch: new pmap=%p old pmap=%p"
+	    , %g1, %g2, %g3, 8, 9, 10)
+	stx	%l1, [%g1 + KTR_PARM1]
+	stx	%l2, [%g1 + KTR_PARM2]
+10:
+#endif
+
+	/*
+	 * If they are the same we are done.
+	 */
+	cmp	%l2, %l1
+	be,a,pn	%xcc, 8f
+	 nop
+
+	/*
+	 * If the new process is a kernel thread we can just leave the old
+	 * context active and avoid recycling its context number.
+	 */
+	SET(vmspace0, %i4, %i3)
+	cmp	%i5, %i3
+	be,a,pn	%xcc, 8f
+	 nop
+
+	/*
+	 * If there was no non-kernel pmap, don't try to deactivate it.
+	 */
+	brz,pn	%l2, 3f
+	 lduw	[PCPU(CPUID)], %l3
+
+	/*
+	 * Mark the pmap of the last non-kernel vmspace to run as no longer
+	 * active on this CPU.
+	 */
+	mov	_NCPUBITS, %l5
+	udivx	%l3, %l5, %l6
+	srl	%l6, 0, %l4
+	sllx	%l4, PTR_SHIFT, %l4
+	add	%l4, PM_ACTIVE, %l4
+	smul	%l6, %l5, %l5
+	sub	%l3, %l5, %l5
+	mov	1, %l6
+	sllx	%l6, %l5, %l5
+#ifdef SMP
+	add	%l2, %l4, %l4
+	membar	#LoadStore | #StoreStore
+	ATOMIC_CLEAR_LONG(%l4, %l6, %l7, %l5)
+#else
+	ldx	[%l2 + %l4], %l6
+	andn	%l6, %l5, %l6
+	stx	%l6, [%l2 + %l4]
+#endif
+
+	/*
+	 * Take away its context number.
+	 */
+	sllx	%l3, INT_SHIFT, %l3
+	add	%l2, PM_CONTEXT, %l4
+	mov	-1, %l5
+	stw	%l5, [%l3 + %l4]
+
+3:	cmp	%i2, %g0
+	be,pn	%xcc, 4f
+	 add	%i0, TD_LOCK, %l4
+#if defined(SCHED_ULE) && defined(SMP)
+	membar	#LoadStore | #StoreStore
+	ATOMIC_STORE_LONG(%l4, %l6, %l7, %i2)
+#else
+	stx	%i2, [%l4]
+#endif
+
+	/*
+	 * Find a new TLB context.  If we've run out we have to flush all
+	 * user mappings from the TLB and reset the context numbers.
+	 */
+4:	lduw	[PCPU(TLB_CTX)], %i3
+	lduw	[PCPU(TLB_CTX_MAX)], %i4
+	cmp	%i3, %i4
+	bne,a,pt %xcc, 5f
+	 nop
+	SET(tlb_flush_user, %i5, %i4)
+	ldx	[%i4], %i5
+	call	%i5
+	 lduw	[PCPU(TLB_CTX_MIN)], %i3
+
+	/*
+	 * Advance next free context.
+	 */
+5:	add	%i3, 1, %i4
+	stw	%i4, [PCPU(TLB_CTX)]
+
+	/*
+	 * Set the new context number in the pmap.
+	 */
+	lduw	[PCPU(CPUID)], %l3
+	sllx	%l3, INT_SHIFT, %i4
+	add	%l1, PM_CONTEXT, %i5
+	stw	%i3, [%i4 + %i5]
+
+	/*
+	 * Mark the pmap as active on this CPU.
+	 */
+	mov	_NCPUBITS, %l5
+	udivx	%l3, %l5, %l6
+	srl	%l6, 0, %l4
+	sllx	%l4, PTR_SHIFT, %l4
+	add	%l4, PM_ACTIVE, %l4
+	smul	%l6, %l5, %l5
+	sub	%l3, %l5, %l5
+	mov	1, %l6
+	sllx	%l6, %l5, %l5
+#ifdef SMP
+	add	%l1, %l4, %l4
+	ATOMIC_SET_LONG(%l4, %l6, %l7, %l5)
+#else
+	ldx	[%l1 + %l4], %l6
+	or	%l6, %l5, %l6
+	stx	%l6, [%l1 + %l4]
+#endif
+
+	/*
+	 * Make note of the change in pmap.
+	 */
+#ifdef SMP
+	PCPU_ADDR(PMAP, %l4)
+	ATOMIC_STORE_LONG(%l4, %l5, %l6, %l1)
+#else
+	stx	%l1, [PCPU(PMAP)]
+#endif
+
+	/*
+	 * Fiddle the hardware bits.  Set the TSB registers and install the
+	 * new context number in the CPU.
+	 */
+	ldx	[%l1 + PM_TSB], %i4
+	mov	AA_DMMU_TSB, %i5
+	stxa	%i4, [%i5] ASI_DMMU
+	mov	AA_IMMU_TSB, %i5
+	stxa	%i4, [%i5] ASI_IMMU
+	setx	TLB_CXR_PGSZ_MASK, %i5, %i4
+	mov	AA_DMMU_PCXR, %i5
+	ldxa	[%i5] ASI_DMMU, %l1
+	and	%l1, %i4, %l1
+	or	%i3, %l1, %i3
+	sethi	%hi(KERNBASE), %i4
+	stxa	%i3, [%i5] ASI_DMMU
+	flush	%i4
+
+6:
+#if defined(SCHED_ULE) && defined(SMP)
+	SET(blocked_lock, %l2, %l1)
+	add	%i1, TD_LOCK, %l2
+7:
+	ATOMIC_LOAD_LONG(%l2, %l3)
+	cmp	%l1, %l3
+	be,a,pn	%xcc, 7b
+	 nop
+#endif
+
+	/*
+	 * Done, return and load the new process's window from the stack.
+	 */
+	ret
+	 restore
+
+8:	cmp	%i2, %g0
+	be,pn	%xcc, 6b
+	 add	%i0, TD_LOCK, %l4
+#if defined(SCHED_ULE) && defined(SMP)
+	membar	#LoadStore | #StoreStore
+	ATOMIC_STORE_LONG(%l4, %l6, %l7, %i2)
+	ba,pt	%xcc, 6b
+	 nop
+#else
+	ba,pt	%xcc, 6b
+	 stx	%i2, [%l4]
+#endif
+END(cpu_switch)
+
+ENTRY(savectx)
+	save	%sp, -CCFSZ, %sp
+	flushw
+	call	savefpctx
+	 add	%i0, PCB_UFP, %o0
+	stx	%fp, [%i0 + PCB_SP]
+	stx	%i7, [%i0 + PCB_PC]
+	ret
+	 restore %g0, 0, %o0
+END(savectx)
+
+/*
+ * void savefpctx(uint32_t *);
+ */
+ENTRY(savefpctx)
+	wr	%g0, FPRS_FEF, %fprs
+	wr	%g0, ASI_BLK_S, %asi
+	stda	%f0, [%o0 + (0 * 64)] %asi
+	stda	%f16, [%o0 + (1 * 64)] %asi
+	stda	%f32, [%o0 + (2 * 64)] %asi
+	stda	%f48, [%o0 + (3 * 64)] %asi
+	membar	#Sync
+	retl
+	 wr	%g0, 0, %fprs
+END(savefpctx)


Property changes on: trunk/sys/sparc64/sparc64/swtch.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/sys_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/sys_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/sys_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,156 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * $FreeBSD: stable/10/sys/sparc64/sparc64/sys_machdep.c 280258 2015-03-19 13:37:36Z rwatson $
+ */
+
+#include "opt_capsicum.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/capsicum.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/sysproto.h>
+
+#include <machine/md_var.h>
+#include <machine/utrap.h>
+#include <machine/sysarch.h>
+
+static int sparc_sigtramp_install(struct thread *td, char *args);
+static int sparc_utrap_install(struct thread *td, char *args);
+
+#ifndef	_SYS_SYSPROTO_H_
+struct sysarch_args {
+	int	op;
+	char	*parms;
+};
+#endif
+
+int
+sysarch(struct thread *td, struct sysarch_args *uap)
+{
+	int error;
+
+#ifdef CAPABILITY_MODE
+	/*
+	 * When adding new operations, add a new case statement here to
+	 * explicitly indicate whether or not the operation is safe to
+	 * perform in capability mode.
+	 */
+	if (IN_CAPABILITY_MODE(td)) {
+		switch (uap->op) {
+		case SPARC_SIGTRAMP_INSTALL:
+		case SPARC_UTRAP_INSTALL:
+			break;
+
+		default:
+#ifdef KTRACE
+			if (KTRPOINT(td, KTR_CAPFAIL))
+				ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL);
+#endif
+			return (ECAPMODE);
+		}
+	}
+#endif
+
+	mtx_lock(&Giant);
+	switch (uap->op) {
+	case SPARC_SIGTRAMP_INSTALL:
+		error = sparc_sigtramp_install(td, uap->parms);
+		break;
+	case SPARC_UTRAP_INSTALL:
+		error = sparc_utrap_install(td, uap->parms);
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	mtx_unlock(&Giant);
+	return (error);
+}
+
+static int
+sparc_sigtramp_install(struct thread *td, char *args)
+{
+	struct sparc_sigtramp_install_args sia;
+	struct proc *p;
+	int error;
+
+	p = td->td_proc;
+	if ((error = copyin(args, &sia, sizeof(sia))) != 0)
+		return (error);
+	if (sia.sia_old != NULL) {
+		if (suword(sia.sia_old, (long)p->p_md.md_sigtramp) != 0)
+			return (EFAULT);
+	}
+	p->p_md.md_sigtramp = sia.sia_new;
+	return (0);
+}
+
+static int
+sparc_utrap_install(struct thread *td, char *args)
+{
+	struct sparc_utrap_install_args uia;
+	struct sparc_utrap_args ua;
+	struct md_utrap *ut;
+	int error;
+	int i;
+
+	ut = td->td_proc->p_md.md_utrap;
+	if ((error = copyin(args, &uia, sizeof(uia))) != 0)
+		return (error);
+	if (uia.num < 0 || uia.num > UT_MAX ||
+	    (uia.handlers == NULL && uia.num > 0))
+		return (EINVAL);
+	for (i = 0; i < uia.num; i++) {
+		if ((error = copyin(&uia.handlers[i], &ua, sizeof(ua))) != 0)
+			return (error);
+		if (ua.type != UTH_NOCHANGE &&
+		    (ua.type < 0 || ua.type >= UT_MAX))
+			return (EINVAL);
+		if (ua.old_deferred != NULL) {
+			if ((error = suword(ua.old_deferred, 0)) != 0)
+				return (error);
+		}
+		if (ua.old_precise != NULL) {
+			error = suword(ua.old_precise,
+			    ut != NULL ? (long)ut->ut_precise[ua.type] : 0);
+			if (error != 0)
+				return (error);
+		}
+		if (ua.type != UTH_NOCHANGE) {
+			if (ut == NULL) {
+				ut = utrap_alloc();
+				td->td_proc->p_md.md_utrap = ut;
+			}
+			ut->ut_precise[ua.type] = ua.new_precise;
+		}
+	}
+	return (0);
+}


Property changes on: trunk/sys/sparc64/sparc64/sys_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/tick.c
===================================================================
--- trunk/sys/sparc64/sparc64/tick.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/tick.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,413 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * Copyright (c) 2005, 2008 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/tick.c 286055 2015-07-30 02:06:29Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
+#include <sys/smp.h>
+#include <sys/sysctl.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/frame.h>
+#include <machine/intr_machdep.h>
+#include <machine/smp.h>
+#include <machine/tick.h>
+#include <machine/ver.h>
+
+#define	TICK_QUALITY_MP	10
+#define	TICK_QUALITY_UP	1000
+
+static SYSCTL_NODE(_machdep, OID_AUTO, tick, CTLFLAG_RD, 0, "tick statistics");
+
+static int adjust_edges = 0;
+SYSCTL_INT(_machdep_tick, OID_AUTO, adjust_edges, CTLFLAG_RD, &adjust_edges,
+    0, "total number of times tick interrupts got more than 12.5% behind");
+
+static int adjust_excess = 0;
+SYSCTL_INT(_machdep_tick, OID_AUTO, adjust_excess, CTLFLAG_RD, &adjust_excess,
+    0, "total number of ignored tick interrupts");
+
+static int adjust_missed = 0;
+SYSCTL_INT(_machdep_tick, OID_AUTO, adjust_missed, CTLFLAG_RD, &adjust_missed,
+    0, "total number of missed tick interrupts");
+
+static int adjust_ticks = 0;
+SYSCTL_INT(_machdep_tick, OID_AUTO, adjust_ticks, CTLFLAG_RD, &adjust_ticks,
+    0, "total number of tick interrupts with adjustment");
+
+u_int tick_et_use_stick = 0;
+SYSCTL_INT(_machdep_tick, OID_AUTO, tick_et_use_stick, CTLFLAG_RD,
+    &tick_et_use_stick, 0, "tick event timer uses STICK instead of TICK");
+
+typedef uint64_t rd_tick_t(void);
+static rd_tick_t *rd_tick;
+typedef void wr_tick_cmpr_t(uint64_t);
+static wr_tick_cmpr_t *wr_tick_cmpr;
+
+static struct timecounter stick_tc;
+static struct eventtimer tick_et;
+static struct timecounter tick_tc;
+
+#ifdef SMP
+static timecounter_get_t stick_get_timecount_mp;
+#endif
+static timecounter_get_t stick_get_timecount_up;
+static rd_tick_t stick_rd;
+static wr_tick_cmpr_t stick_wr_cmpr;
+static int tick_et_start(struct eventtimer *et, sbintime_t first,
+    sbintime_t period);
+static int tick_et_stop(struct eventtimer *et);
+#ifdef SMP
+static timecounter_get_t tick_get_timecount_mp;
+#endif
+static timecounter_get_t tick_get_timecount_up;
+static void tick_intr(struct trapframe *tf);
+static inline void tick_process(struct trapframe *tf);
+static rd_tick_t tick_rd;
+static wr_tick_cmpr_t tick_wr_cmpr;
+static wr_tick_cmpr_t tick_wr_cmpr_bbwar;
+static uint64_t tick_cputicks(void);
+
+static uint64_t
+stick_rd(void)
+{
+
+	return (rdstick());
+}
+
+static void
+stick_wr_cmpr(uint64_t tick)
+{
+
+	wrstickcmpr(tick, 0);
+}
+
+static uint64_t
+tick_rd(void)
+{
+
+	return (rd(tick));
+}
+
+static void
+tick_wr_cmpr(uint64_t tick_cmpr)
+{
+
+	wrtickcmpr(tick_cmpr, 0);
+}
+
+static void
+tick_wr_cmpr_bbwar(uint64_t tick_cmpr)
+{
+
+	wrtickcmpr_bbwar(tick_cmpr, 0);
+}
+
+static uint64_t
+tick_cputicks(void)
+{
+
+	return (rd(tick));
+}
+
+void
+cpu_initclocks(void)
+{
+	uint32_t clock, sclock;
+
+	clock = PCPU_GET(clock);
+	sclock = 0;
+	if (PCPU_GET(impl) == CPU_IMPL_SPARC64V ||
+	    PCPU_GET(impl) >= CPU_IMPL_ULTRASPARCIII) {
+		if (OF_getprop(OF_peer(0), "stick-frequency", &sclock,
+		    sizeof(sclock)) == -1) {
+			panic("%s: could not determine STICK frequency",
+			    __func__);
+		}
+	}
+	/*
+	 * Given that the STICK timers typically are driven at rather low
+	 * frequencies they shouldn't be used except when really necessary.
+	 */
+	if (tick_et_use_stick != 0) {
+		rd_tick = stick_rd;
+		wr_tick_cmpr = stick_wr_cmpr;
+		/*
+		 * We don't provide a CPU ticker as long as the frequency
+		 * supplied isn't actually used per-CPU.
+		 */
+	} else {
+		rd_tick = tick_rd;
+		if (PCPU_GET(impl) >= CPU_IMPL_ULTRASPARCI &&
+		    PCPU_GET(impl) < CPU_IMPL_ULTRASPARCIII)
+			wr_tick_cmpr = tick_wr_cmpr_bbwar;
+		else
+			wr_tick_cmpr = tick_wr_cmpr;
+		set_cputicker(tick_cputicks, clock, 0);
+	}
+	intr_setup(PIL_TICK, tick_intr, -1, NULL, NULL);
+
+	/*
+	 * Initialize the (S)TICK-based timecounter(s).
+	 * Note that we (try to) sync the (S)TICK timers of APs with the BSP
+	 * during their startup but not afterwards.  The resulting drift can
+	 * cause problems when the time is calculated based on (S)TICK values
+	 * read on different CPUs.  Thus we always read the register on the
+	 * BSP (if necessary via an IPI as sched_bind(9) isn't available in
+	 * all circumstances) and use a low quality for the otherwise high
+	 * quality (S)TICK timers in the MP case.
+	 */
+	tick_tc.tc_get_timecount = tick_get_timecount_up;
+	tick_tc.tc_counter_mask = ~0u;
+	tick_tc.tc_frequency = clock;
+	tick_tc.tc_name = "tick";
+	tick_tc.tc_quality = TICK_QUALITY_UP;
+#ifdef SMP
+	if (cpu_mp_probe()) {
+		tick_tc.tc_get_timecount = tick_get_timecount_mp;
+		tick_tc.tc_quality = TICK_QUALITY_MP;
+	}
+#endif
+	tc_init(&tick_tc);
+	if (sclock != 0) {
+		stick_tc.tc_get_timecount = stick_get_timecount_up;
+		stick_tc.tc_counter_mask = ~0u;
+		stick_tc.tc_frequency = sclock;
+		stick_tc.tc_name = "stick";
+		stick_tc.tc_quality = TICK_QUALITY_UP;
+#ifdef SMP
+		if (cpu_mp_probe()) {
+			stick_tc.tc_get_timecount = stick_get_timecount_mp;
+			stick_tc.tc_quality = TICK_QUALITY_MP;
+		}
+#endif
+		tc_init(&stick_tc);
+	}
+	tick_et.et_name = tick_et_use_stick ? "stick" : "tick";
+	tick_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT |
+	    ET_FLAGS_PERCPU;
+	tick_et.et_quality = 1000;
+	tick_et.et_frequency = tick_et_use_stick ? sclock : clock;
+	tick_et.et_min_period = 0x00010000LLU; /* To be safe. */
+	tick_et.et_max_period = (0xfffffffeLLU << 32) / tick_et.et_frequency;
+	tick_et.et_start = tick_et_start;
+	tick_et.et_stop = tick_et_stop;
+	tick_et.et_priv = NULL;
+	et_register(&tick_et);
+
+	cpu_initclocks_bsp();
+}
+
+static inline void
+tick_process(struct trapframe *tf)
+{
+	struct trapframe *oldframe;
+	struct thread *td;
+
+	td = curthread;
+	td->td_intr_nesting_level++;
+	critical_enter();
+	if (tick_et.et_active) {
+		oldframe = td->td_intr_frame;
+		td->td_intr_frame = tf;
+		tick_et.et_event_cb(&tick_et, tick_et.et_arg);
+		td->td_intr_frame = oldframe;
+	}
+	td->td_intr_nesting_level--;
+	critical_exit();
+}
+
+static void
+tick_intr(struct trapframe *tf)
+{
+	u_long adj, ref, tick, tick_increment;
+	long delta;
+	register_t s;
+	int count;
+
+	tick_increment = PCPU_GET(tickincrement);
+	if (tick_increment != 0) {
+		/*
+		 * NB: the sequence of reading the (S)TICK register,
+		 * calculating the value of the next tick and writing it to
+		 * the (S)TICK_COMPARE register must not be interrupted, not
+		 * even by an IPI, otherwise a value that is in the past could
+		 * be written in the worst case and thus causing the periodic
+		 * timer to stop.
+		 */
+		s = intr_disable();
+		adj = PCPU_GET(tickadj);
+		tick = rd_tick();
+		wr_tick_cmpr(tick + tick_increment - adj);
+		intr_restore(s);
+		ref = PCPU_GET(tickref);
+		delta = tick - ref;
+		count = 0;
+		while (delta >= tick_increment) {
+			tick_process(tf);
+			delta -= tick_increment;
+			ref += tick_increment;
+			if (adj != 0)
+				adjust_ticks++;
+			count++;
+		}
+		if (count > 0) {
+			adjust_missed += count - 1;
+			if (delta > (tick_increment >> 3)) {
+				if (adj == 0)
+					adjust_edges++;
+				adj = tick_increment >> 4;
+			} else
+				adj = 0;
+		} else {
+			adj = 0;
+			adjust_excess++;
+		}
+		PCPU_SET(tickref, ref);
+		PCPU_SET(tickadj, adj);
+	} else
+		tick_process(tf);
+}
+
+static u_int
+stick_get_timecount_up(struct timecounter *tc)
+{
+
+	return ((u_int)rdstick());
+}
+
+static u_int
+tick_get_timecount_up(struct timecounter *tc)
+{
+
+	return ((u_int)rd(tick));
+}
+
+#ifdef SMP
+static u_int
+stick_get_timecount_mp(struct timecounter *tc)
+{
+	static u_long stick;
+
+	sched_pin();
+	if (curcpu == 0)
+		stick = rdstick();
+	else
+		ipi_wait(ipi_rd(0, tl_ipi_stick_rd, &stick));
+	sched_unpin();
+	return (stick);
+}
+
+static u_int
+tick_get_timecount_mp(struct timecounter *tc)
+{
+	static u_long tick;
+
+	sched_pin();
+	if (curcpu == 0)
+		tick = rd(tick);
+	else
+		ipi_wait(ipi_rd(0, tl_ipi_tick_rd, &tick));
+	sched_unpin();
+	return (tick);
+}
+#endif
+
+static int
+tick_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
+{
+	u_long base, div, fdiv;
+	register_t s;
+
+	if (period != 0)
+		div = (tick_et.et_frequency * period) >> 32;
+	else
+		div = 0;
+	if (first != 0)
+		fdiv = (tick_et.et_frequency * first) >> 32;
+	else
+		fdiv = div;
+	PCPU_SET(tickincrement, div);
+
+	/*
+	 * Try to make the (S)TICK interrupts as synchronously as possible
+	 * on all CPUs to avoid inaccuracies for migrating processes.  Leave
+	 * out one tick to make sure that it is not missed.
+	 */
+	s = intr_disable();
+	base = rd_tick();
+	if (div != 0) {
+		PCPU_SET(tickadj, 0);
+		base = roundup(base, div);
+	}
+	PCPU_SET(tickref, base);
+	wr_tick_cmpr(base + fdiv);
+	intr_restore(s);
+	return (0);
+}
+
+static int
+tick_et_stop(struct eventtimer *et)
+{
+
+	PCPU_SET(tickincrement, 0);
+	tick_stop(PCPU_GET(impl));
+	return (0);
+}
+
+void
+tick_clear(u_int cpu_impl)
+{
+
+	if (cpu_impl == CPU_IMPL_SPARC64V ||
+	    cpu_impl >= CPU_IMPL_ULTRASPARCIII)
+		wrstick(0, 0);
+	wrpr(tick, 0, 0);
+}
+
+void
+tick_stop(u_int cpu_impl)
+{
+
+	if (cpu_impl == CPU_IMPL_SPARC64V ||
+	    cpu_impl >= CPU_IMPL_ULTRASPARCIII)
+		wrstickcmpr(1L << 63, 0);
+	wrtickcmpr(1L << 63, 0);
+}


Property changes on: trunk/sys/sparc64/sparc64/tick.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/tlb.c
===================================================================
--- trunk/sys/sparc64/sparc64/tlb.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/tlb.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,148 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/tlb.c 223346 2011-06-20 21:31:01Z marius $");
+
+#include "opt_pmap.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ktr.h>
+#include <sys/pcpu.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+#include <sys/sysctl.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/pmap.h>
+#include <machine/smp.h>
+#include <machine/tlb.h>
+#include <machine/vmparam.h>
+
+PMAP_STATS_VAR(tlb_ncontext_demap);
+PMAP_STATS_VAR(tlb_npage_demap);
+PMAP_STATS_VAR(tlb_nrange_demap);
+
+tlb_flush_nonlocked_t *tlb_flush_nonlocked;
+tlb_flush_user_t *tlb_flush_user;
+
+/*
+ * Some tlb operations must be atomic, so no interrupt or trap can be allowed
+ * while they are in progress. Traps should not happen, but interrupts need to
+ * be explicitely disabled. critical_enter() cannot be used here, since it only
+ * disables soft interrupts.
+ */
+
+void
+tlb_context_demap(struct pmap *pm)
+{
+	void *cookie;
+	register_t s;
+
+	/*
+	 * It is important that we are not interrupted or preempted while
+	 * doing the IPIs. The interrupted CPU may hold locks, and since
+	 * it will wait for the CPU that sent the IPI, this can lead
+	 * to a deadlock when an interrupt comes in on that CPU and it's
+	 * handler tries to grab one of that locks. This will only happen for
+	 * spin locks, but these IPI types are delivered even if normal
+	 * interrupts are disabled, so the lock critical section will not
+	 * protect the target processor from entering the IPI handler with
+	 * the lock held.
+	 */
+	PMAP_STATS_INC(tlb_ncontext_demap);
+	cookie = ipi_tlb_context_demap(pm);
+	s = intr_disable();
+	if (CPU_ISSET(PCPU_GET(cpuid), &pm->pm_active)) {
+		KASSERT(pm->pm_context[curcpu] != -1,
+		    ("tlb_context_demap: inactive pmap?"));
+		stxa(TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, ASI_DMMU_DEMAP, 0);
+		stxa(TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, ASI_IMMU_DEMAP, 0);
+		flush(KERNBASE);
+	}
+	intr_restore(s);
+	ipi_wait(cookie);
+}
+
+void
+tlb_page_demap(struct pmap *pm, vm_offset_t va)
+{
+	u_long flags;
+	void *cookie;
+	register_t s;
+
+	PMAP_STATS_INC(tlb_npage_demap);
+	cookie = ipi_tlb_page_demap(pm, va);
+	s = intr_disable();
+	if (CPU_ISSET(PCPU_GET(cpuid), &pm->pm_active)) {
+		KASSERT(pm->pm_context[curcpu] != -1,
+		    ("tlb_page_demap: inactive pmap?"));
+		if (pm == kernel_pmap)
+			flags = TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE;
+		else
+			flags = TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE;
+
+		stxa(TLB_DEMAP_VA(va) | flags, ASI_DMMU_DEMAP, 0);
+		stxa(TLB_DEMAP_VA(va) | flags, ASI_IMMU_DEMAP, 0);
+		flush(KERNBASE);
+	}
+	intr_restore(s);
+	ipi_wait(cookie);
+}
+
+void
+tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
+{
+	vm_offset_t va;
+	void *cookie;
+	u_long flags;
+	register_t s;
+
+	PMAP_STATS_INC(tlb_nrange_demap);
+	cookie = ipi_tlb_range_demap(pm, start, end);
+	s = intr_disable();
+	if (CPU_ISSET(PCPU_GET(cpuid), &pm->pm_active)) {
+		KASSERT(pm->pm_context[curcpu] != -1,
+		    ("tlb_range_demap: inactive pmap?"));
+		if (pm == kernel_pmap)
+			flags = TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE;
+		else
+			flags = TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE;
+
+		for (va = start; va < end; va += PAGE_SIZE) {
+			stxa(TLB_DEMAP_VA(va) | flags, ASI_DMMU_DEMAP, 0);
+			stxa(TLB_DEMAP_VA(va) | flags, ASI_IMMU_DEMAP, 0);
+			flush(KERNBASE);
+		}
+	}
+	intr_restore(s);
+	ipi_wait(cookie);
+}


Property changes on: trunk/sys/sparc64/sparc64/tlb.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/trap.c
===================================================================
--- trunk/sys/sparc64/sparc64/trap.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/trap.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,640 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001, Jake Burkholder
+ * Copyright (C) 1994, David Greenman
+ * Copyright (c) 1990, 1993
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the University of Utah, and 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
+ *
+ *	from: @(#)trap.c        7.4 (Berkeley) 5/13/91
+ *	from: FreeBSD: src/sys/i386/i386/trap.c,v 1.197 2001/07/19
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/trap.c 240244 2012-09-08 18:27:11Z attilio $");
+
+#include "opt_ddb.h"
+#include "opt_ktr.h"
+
+#include <sys/param.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+#include <sys/pcpu.h>
+#include <sys/pioctl.h>
+#include <sys/ptrace.h>
+#include <sys/proc.h>
+#include <sys/smp.h>
+#include <sys/signalvar.h>
+#include <sys/syscall.h>
+#include <sys/sysctl.h>
+#include <sys/sysent.h>
+#include <sys/vmmeter.h>
+#include <security/audit/audit.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_param.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_page.h>
+
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/intr_machdep.h>
+#include <machine/ofw_machdep.h>
+#include <machine/pcb.h>
+#include <machine/smp.h>
+#include <machine/trap.h>
+#include <machine/tstate.h>
+#include <machine/tte.h>
+#include <machine/tlb.h>
+#include <machine/tsb.h>
+#include <machine/watch.h>
+
+void trap(struct trapframe *tf);
+void syscall(struct trapframe *tf);
+
+static int trap_cecc(void);
+static int trap_pfault(struct thread *td, struct trapframe *tf);
+
+extern char copy_fault[];
+extern char copy_nofault_begin[];
+extern char copy_nofault_end[];
+
+extern char fs_fault[];
+extern char fs_nofault_begin[];
+extern char fs_nofault_end[];
+extern char fs_nofault_intr_begin[];
+extern char fs_nofault_intr_end[];
+
+extern char fas_fault[];
+extern char fas_nofault_begin[];
+extern char fas_nofault_end[];
+
+const char *const trap_msg[] = {
+	"reserved",
+	"instruction access exception",
+	"instruction access error",
+	"instruction access protection",
+	"illtrap instruction",
+	"illegal instruction",
+	"privileged opcode",
+	"floating point disabled",
+	"floating point exception ieee 754",
+	"floating point exception other",
+	"tag overflow",
+	"division by zero",
+	"data access exception",
+	"data access error",
+	"data access protection",
+	"memory address not aligned",
+	"privileged action",
+	"async data error",
+	"trap instruction 16",
+	"trap instruction 17",
+	"trap instruction 18",
+	"trap instruction 19",
+	"trap instruction 20",
+	"trap instruction 21",
+	"trap instruction 22",
+	"trap instruction 23",
+	"trap instruction 24",
+	"trap instruction 25",
+	"trap instruction 26",
+	"trap instruction 27",
+	"trap instruction 28",
+	"trap instruction 29",
+	"trap instruction 30",
+	"trap instruction 31",
+	"fast instruction access mmu miss",
+	"fast data access mmu miss",
+	"interrupt",
+	"physical address watchpoint",
+	"virtual address watchpoint",
+	"corrected ecc error",
+	"spill",
+	"fill",
+	"fill",
+	"breakpoint",
+	"clean window",
+	"range check",
+	"fix alignment",
+	"integer overflow",
+	"syscall",
+	"restore physical watchpoint",
+	"restore virtual watchpoint",
+	"kernel stack fault",
+};
+
+static const int trap_sig[] = {
+	SIGILL,			/* reserved */
+	SIGILL,			/* instruction access exception */
+	SIGILL,			/* instruction access error */
+	SIGILL,			/* instruction access protection */
+	SIGILL,			/* illtrap instruction */
+	SIGILL,			/* illegal instruction */
+	SIGBUS,			/* privileged opcode */
+	SIGFPE,			/* floating point disabled */
+	SIGFPE,			/* floating point exception ieee 754 */
+	SIGFPE,			/* floating point exception other */
+	SIGEMT,			/* tag overflow */
+	SIGFPE,			/* division by zero */
+	SIGILL,			/* data access exception */
+	SIGILL,			/* data access error */
+	SIGBUS,			/* data access protection */
+	SIGBUS,			/* memory address not aligned */
+	SIGBUS,			/* privileged action */
+	SIGBUS,			/* async data error */
+	SIGILL,			/* trap instruction 16 */
+	SIGILL,			/* trap instruction 17 */
+	SIGILL,			/* trap instruction 18 */
+	SIGILL,			/* trap instruction 19 */
+	SIGILL,			/* trap instruction 20 */
+	SIGILL,			/* trap instruction 21 */
+	SIGILL,			/* trap instruction 22 */
+	SIGILL,			/* trap instruction 23 */
+	SIGILL,			/* trap instruction 24 */
+	SIGILL,			/* trap instruction 25 */
+	SIGILL,			/* trap instruction 26 */
+	SIGILL,			/* trap instruction 27 */
+	SIGILL,			/* trap instruction 28 */
+	SIGILL,			/* trap instruction 29 */
+	SIGILL,			/* trap instruction 30 */
+	SIGILL,			/* trap instruction 31 */
+	SIGSEGV,		/* fast instruction access mmu miss */
+	SIGSEGV,		/* fast data access mmu miss */
+	-1,			/* interrupt */
+	-1,			/* physical address watchpoint */
+	-1,			/* virtual address watchpoint */
+	-1,			/* corrected ecc error */
+	SIGILL,			/* spill */
+	SIGILL,			/* fill */
+	SIGILL,			/* fill */
+	SIGTRAP,		/* breakpoint */
+	SIGILL,			/* clean window */
+	SIGILL,			/* range check */
+	SIGILL,			/* fix alignment */
+	SIGILL,			/* integer overflow */
+	SIGSYS,			/* syscall */
+	-1,			/* restore physical watchpoint */
+	-1,			/* restore virtual watchpoint */
+	-1,			/* kernel stack fault */
+};
+
+CTASSERT(sizeof(trap_msg) / sizeof(*trap_msg) == T_MAX);
+CTASSERT(sizeof(trap_sig) / sizeof(*trap_sig) == T_MAX);
+
+CTASSERT(sizeof(struct trapframe) == 256);
+
+int debugger_on_signal = 0;
+SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW,
+    &debugger_on_signal, 0, "");
+
+u_int corrected_ecc = 0;
+SYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0,
+    "corrected ECC errors");
+
+/*
+ * SUNW,set-trap-table allows to take over %tba from the PROM, which
+ * will turn off interrupts and handle outstanding ones while doing so,
+ * in a safe way.
+ */
+void
+sun4u_set_traptable(void *tba_addr)
+{
+	static struct {
+		cell_t name;
+		cell_t nargs;
+		cell_t nreturns;
+		cell_t tba_addr;
+	} args = {
+		(cell_t)"SUNW,set-trap-table",
+		1,
+		0,
+	};
+
+	args.tba_addr = (cell_t)tba_addr;
+	ofw_entry(&args);
+}
+
+void
+trap(struct trapframe *tf)
+{
+	struct thread *td;
+	struct proc *p;
+	int error;
+	int sig;
+	register_t addr;
+	ksiginfo_t ksi;
+
+	td = curthread;
+
+	CTR4(KTR_TRAP, "trap: %p type=%s (%s) pil=%#lx", td,
+	    trap_msg[tf->tf_type & ~T_KERNEL],
+	    (TRAPF_USERMODE(tf) ? "user" : "kernel"), rdpr(pil));
+
+	PCPU_INC(cnt.v_trap);
+
+	if ((tf->tf_tstate & TSTATE_PRIV) == 0) {
+		KASSERT(td != NULL, ("trap: curthread NULL"));
+		KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
+
+		p = td->td_proc;
+		td->td_pticks = 0;
+		td->td_frame = tf;
+		addr = tf->tf_tpc;
+		if (td->td_ucred != p->p_ucred)
+			cred_update_thread(td);
+
+		switch (tf->tf_type) {
+		case T_DATA_MISS:
+		case T_DATA_PROTECTION:
+			addr = tf->tf_sfar;
+			/* FALLTHROUGH */
+		case T_INSTRUCTION_MISS:
+			sig = trap_pfault(td, tf);
+			break;
+		case T_FILL:
+			sig = rwindow_load(td, tf, 2);
+			break;
+		case T_FILL_RET:
+			sig = rwindow_load(td, tf, 1);
+			break;
+		case T_SPILL:
+			sig = rwindow_save(td);
+			break;
+		case T_CORRECTED_ECC_ERROR:
+			sig = trap_cecc();
+			break;
+		default:
+			if (tf->tf_type > T_MAX)
+				panic("trap: bad trap type %#lx (user)",
+				    tf->tf_type);
+			else if (trap_sig[tf->tf_type] == -1)
+				panic("trap: %s (user)",
+				    trap_msg[tf->tf_type]);
+			sig = trap_sig[tf->tf_type];
+			break;
+		}
+
+		if (sig != 0) {
+			/* Translate fault for emulators. */
+			if (p->p_sysent->sv_transtrap != NULL) {
+				sig = p->p_sysent->sv_transtrap(sig,
+				    tf->tf_type);
+			}
+			if (debugger_on_signal &&
+			    (sig == 4 || sig == 10 || sig == 11))
+				kdb_enter(KDB_WHY_TRAPSIG, "trapsig");
+			ksiginfo_init_trap(&ksi);
+			ksi.ksi_signo = sig;
+			ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */
+			ksi.ksi_addr = (void *)addr;
+			ksi.ksi_trapno = (int)tf->tf_type;
+			trapsignal(td, &ksi);
+		}
+
+		userret(td, tf);
+	} else {
+		KASSERT((tf->tf_type & T_KERNEL) != 0,
+		    ("trap: kernel trap isn't"));
+
+		if (kdb_active) {
+			kdb_reenter();
+			return;
+		}
+
+		switch (tf->tf_type & ~T_KERNEL) {
+		case T_BREAKPOINT:
+		case T_KSTACK_FAULT:
+			error = (kdb_trap(tf->tf_type, 0, tf) == 0);
+			TF_DONE(tf);
+			break;
+#ifdef notyet
+		case T_PA_WATCHPOINT:
+		case T_VA_WATCHPOINT:
+			error = db_watch_trap(tf);
+			break;
+#endif
+		case T_DATA_MISS:
+		case T_DATA_PROTECTION:
+		case T_INSTRUCTION_MISS:
+			error = trap_pfault(td, tf);
+			break;
+		case T_DATA_EXCEPTION:
+		case T_MEM_ADDRESS_NOT_ALIGNED:
+			if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 &&
+			    MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) {
+				if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
+				    tf->tf_tpc <= (u_long)copy_nofault_end) {
+					tf->tf_tpc = (u_long)copy_fault;
+					tf->tf_tnpc = tf->tf_tpc + 4;
+					error = 0;
+					break;
+				}
+				if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
+				    tf->tf_tpc <= (u_long)fs_nofault_end) {
+					tf->tf_tpc = (u_long)fs_fault;
+					tf->tf_tnpc = tf->tf_tpc + 4;
+					error = 0;
+					break;
+				}
+			}
+			error = 1;
+			break;
+		case T_DATA_ERROR:
+			/*
+			 * Handle PCI poke/peek as per UltraSPARC IIi
+			 * User's Manual 16.2.1, modulo checking the
+			 * TPC as USIII CPUs generate a precise trap
+			 * instead of a special deferred one.
+			 */
+			if (tf->tf_tpc > (u_long)fas_nofault_begin &&
+			    tf->tf_tpc < (u_long)fas_nofault_end) {
+				cache_flush();
+				cache_enable(PCPU_GET(impl));
+				tf->tf_tpc = (u_long)fas_fault;
+				tf->tf_tnpc = tf->tf_tpc + 4;
+				error = 0;
+				break;
+			}
+			error = 1;
+			break;
+		case T_CORRECTED_ECC_ERROR:
+			error = trap_cecc();
+			break;
+		default:
+			error = 1;
+			break;
+		}
+
+		if (error != 0) {
+			tf->tf_type &= ~T_KERNEL;
+			if (tf->tf_type > T_MAX)
+				panic("trap: bad trap type %#lx (kernel)",
+				    tf->tf_type);
+			panic("trap: %s (kernel)", trap_msg[tf->tf_type]);
+		}
+	}
+	CTR1(KTR_TRAP, "trap: td=%p return", td);
+}
+
+static int
+trap_cecc(void)
+{
+	u_long eee;
+
+	/*
+	 * Turn off (non-)correctable error reporting while we're dealing
+	 * with the error.
+	 */
+	eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG);
+	stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN |
+	    AA_ESTATE_CEEN));
+	/* Flush the caches in order ensure no corrupt data got installed. */
+	cache_flush();
+	/* Ensure the caches are still turned on (should be). */
+	cache_enable(PCPU_GET(impl));
+	/* Clear the error from the AFSR. */
+	stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR));
+	corrected_ecc++;
+	printf("corrected ECC error\n");
+	/* Turn (non-)correctable error reporting back on. */
+	stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee);
+	return (0);
+}
+
+static int
+trap_pfault(struct thread *td, struct trapframe *tf)
+{
+	struct vmspace *vm;
+	struct proc *p;
+	vm_offset_t va;
+	vm_prot_t prot;
+	vm_map_entry_t entry;
+	u_long ctx;
+	int type;
+	int rv;
+
+	if (td == NULL)
+		return (-1);
+	KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL"));
+	KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL"));
+	KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL"));
+
+	p = td->td_proc;
+
+	rv = KERN_SUCCESS;
+	ctx = TLB_TAR_CTX(tf->tf_tar);
+	type = tf->tf_type & ~T_KERNEL;
+	va = TLB_TAR_VA(tf->tf_tar);
+
+	CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx",
+	    td, p->p_vmspace->vm_pmap.pm_context[curcpu], va, ctx);
+
+	if (type == T_DATA_PROTECTION)
+		prot = VM_PROT_WRITE;
+	else {
+		if (type == T_DATA_MISS)
+			prot = VM_PROT_READ;
+		else
+			prot = VM_PROT_READ | VM_PROT_EXECUTE;
+	}
+
+	if (ctx != TLB_CTX_KERNEL) {
+		if ((tf->tf_tstate & TSTATE_PRIV) != 0 &&
+		    (tf->tf_tpc >= (u_long)fs_nofault_intr_begin &&
+		    tf->tf_tpc <= (u_long)fs_nofault_intr_end)) {
+			tf->tf_tpc = (u_long)fs_fault;
+			tf->tf_tnpc = tf->tf_tpc + 4;
+			return (0);
+		}
+
+		/*
+		 * This is a fault on non-kernel virtual memory.
+		 */
+		vm = p->p_vmspace;
+
+		/*
+		 * Keep swapout from messing with us during this
+		 * critical time.
+		 */
+		PROC_LOCK(p);
+		++p->p_lock;
+		PROC_UNLOCK(p);
+
+		/* Fault in the user page. */
+		rv = vm_fault(&vm->vm_map, va, prot, VM_FAULT_NORMAL);
+
+		/*
+		 * Now the process can be swapped again.
+		 */
+		PROC_LOCK(p);
+		--p->p_lock;
+		PROC_UNLOCK(p);
+	} else {
+		/*
+		 * This is a fault on kernel virtual memory.  Attempts to
+		 * access kernel memory from user mode cause privileged
+		 * action traps, not page fault.
+		 */
+		KASSERT(tf->tf_tstate & TSTATE_PRIV,
+		    ("trap_pfault: fault on nucleus context from user mode"));
+
+		if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
+		    tf->tf_tpc <= (u_long)copy_nofault_end) {
+			vm_map_lock_read(kernel_map);
+			if (vm_map_lookup_entry(kernel_map, va, &entry) &&
+			    (entry->eflags & MAP_ENTRY_NOFAULT) != 0) {
+				tf->tf_tpc = (u_long)copy_fault;
+				tf->tf_tnpc = tf->tf_tpc + 4;
+				vm_map_unlock_read(kernel_map);
+				return (0);
+			}
+			vm_map_unlock_read(kernel_map);
+		}
+
+		/*
+		 * We don't have to worry about process locking or stacks in
+		 * the kernel.
+		 */
+		rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL);
+	}
+
+	CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
+	    td, va, rv);
+	if (rv == KERN_SUCCESS)
+		return (0);
+	if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) {
+		if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
+		    tf->tf_tpc <= (u_long)fs_nofault_end) {
+			tf->tf_tpc = (u_long)fs_fault;
+			tf->tf_tnpc = tf->tf_tpc + 4;
+			return (0);
+		}
+		if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
+		    tf->tf_tpc <= (u_long)copy_nofault_end) {
+			tf->tf_tpc = (u_long)copy_fault;
+			tf->tf_tnpc = tf->tf_tpc + 4;
+			return (0);
+		}
+	}
+	return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
+}
+
+/* Maximum number of arguments that can be passed via the out registers. */
+#define	REG_MAXARGS	6
+
+int
+cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+{
+	struct trapframe *tf;
+	struct proc *p;
+	register_t *argp;
+	int reg;
+	int regcnt;
+	int error;
+
+	p = td->td_proc;
+	tf = td->td_frame;
+	reg = 0;
+	regcnt = REG_MAXARGS;
+
+	sa->code = tf->tf_global[1];
+
+	if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
+		sa->code = tf->tf_out[reg++];
+		regcnt--;
+	}
+
+	if (p->p_sysent->sv_mask)
+		sa->code &= p->p_sysent->sv_mask;
+	if (sa->code >= p->p_sysent->sv_size)
+		sa->callp = &p->p_sysent->sv_table[0];
+	else
+		sa->callp = &p->p_sysent->sv_table[sa->code];
+
+	sa->narg = sa->callp->sy_narg;
+	KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]),
+	    ("Too many syscall arguments!"));
+	error = 0;
+	argp = sa->args;
+	bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt);
+	if (sa->narg > regcnt)
+		error = copyin((void *)(tf->tf_out[6] + SPOFF +
+		    offsetof(struct frame, fr_pad[6])), &sa->args[regcnt],
+		    (sa->narg - regcnt) * sizeof(sa->args[0]));
+	if (error == 0) {
+		td->td_retval[0] = 0;
+		td->td_retval[1] = 0;
+	}
+
+	return (error);
+}
+
+#include "../../kern/subr_syscall.c"
+
+/*
+ * Syscall handler
+ * The arguments to the syscall are passed in the out registers by the caller,
+ * and are saved in the trap frame.  The syscall number is passed in %g1 (and
+ * also saved in the trap frame).
+ */
+void
+syscall(struct trapframe *tf)
+{
+	struct thread *td;
+	struct syscall_args sa;
+	int error;
+
+	td = curthread;
+	td->td_frame = tf;
+
+	KASSERT(td != NULL, ("trap: curthread NULL"));
+	KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
+
+	/*
+	 * For syscalls, we don't want to retry the faulting instruction
+	 * (usually), instead we need to advance one instruction.
+	 */
+	td->td_pcb->pcb_tpc = tf->tf_tpc;
+	TF_DONE(tf);
+
+	error = syscallenter(td, &sa);
+	syscallret(td, error, &sa);
+}


Property changes on: trunk/sys/sparc64/sparc64/trap.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/tsb.c
===================================================================
--- trunk/sys/sparc64/sparc64/tsb.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/tsb.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,229 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1997 Berkeley Software Design, Inc. 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. Berkeley Software Design Inc's name may not be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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 BSDI: pmap.c,v 1.28.2.15 2000/04/27 03:10:31 cp Exp
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/tsb.c 247297 2013-02-26 01:00:11Z attilio $");
+
+#include "opt_ddb.h"
+#include "opt_pmap.h"
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/smp.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.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 <machine/cpufunc.h>
+#include <machine/frame.h>
+#include <machine/trap.h>
+#include <machine/pmap.h>
+#include <machine/smp.h>
+#include <machine/tlb.h>
+#include <machine/tsb.h>
+#include <machine/tte.h>
+
+CTASSERT((1 << TTE_SHIFT) == sizeof(struct tte));
+CTASSERT(TSB_BUCKET_MASK < (1 << 12));
+
+PMAP_STATS_VAR(tsb_nrepl);
+PMAP_STATS_VAR(tsb_nlookup_k);
+PMAP_STATS_VAR(tsb_nlookup_u);
+PMAP_STATS_VAR(tsb_nenter_k);
+PMAP_STATS_VAR(tsb_nenter_k_oc);
+PMAP_STATS_VAR(tsb_nenter_u);
+PMAP_STATS_VAR(tsb_nenter_u_oc);
+PMAP_STATS_VAR(tsb_nforeach);
+
+struct tte *tsb_kernel;
+vm_size_t tsb_kernel_mask;
+vm_size_t tsb_kernel_size;
+vm_paddr_t tsb_kernel_phys;
+u_int tsb_kernel_ldd_phys;
+
+struct tte *
+tsb_tte_lookup(pmap_t pm, vm_offset_t va)
+{
+	struct tte *bucket;
+	struct tte *tp;
+	u_long sz;
+	u_int i;
+
+	if (pm == kernel_pmap) {
+		PMAP_STATS_INC(tsb_nlookup_k);
+		tp = tsb_kvtotte(va);
+		if (tte_match(tp, va))
+			return (tp);
+	} else {
+		PMAP_LOCK_ASSERT(pm, MA_OWNED);
+		PMAP_STATS_INC(tsb_nlookup_u);
+		for (sz = TS_MIN; sz <= TS_MAX; sz++) {
+			bucket = tsb_vtobucket(pm, sz, va);
+			for (i = 0; i < TSB_BUCKET_SIZE; i++) {
+				tp = &bucket[i];
+				if (tte_match(tp, va))
+					return (tp);
+			}
+		}
+	}
+	return (NULL);
+}
+
+struct tte *
+tsb_tte_enter(pmap_t pm, vm_page_t m, vm_offset_t va, u_long sz, u_long data)
+{
+	struct tte *bucket;
+	struct tte *rtp;
+	struct tte *tp;
+	vm_offset_t ova;
+	int b0;
+	int i;
+
+	if (DCACHE_COLOR(VM_PAGE_TO_PHYS(m)) != DCACHE_COLOR(va)) {
+		CTR5(KTR_SPARE2,
+	"tsb_tte_enter: off colour va=%#lx pa=%#lx o=%p ot=%d pi=%#lx",
+		    va, VM_PAGE_TO_PHYS(m), m->object,
+		    m->object ? m->object->type : -1,
+		    m->pindex);
+		if (pm == kernel_pmap)
+			PMAP_STATS_INC(tsb_nenter_k_oc);
+		else
+			PMAP_STATS_INC(tsb_nenter_u_oc);
+	}
+
+	rw_assert(&tte_list_global_lock, RA_WLOCKED);
+	PMAP_LOCK_ASSERT(pm, MA_OWNED);
+	if (pm == kernel_pmap) {
+		PMAP_STATS_INC(tsb_nenter_k);
+		tp = tsb_kvtotte(va);
+		KASSERT((tp->tte_data & TD_V) == 0,
+		    ("tsb_tte_enter: replacing valid kernel mapping"));
+		goto enter;
+	}
+	PMAP_STATS_INC(tsb_nenter_u);
+
+	bucket = tsb_vtobucket(pm, sz, va);
+
+	tp = NULL;
+	rtp = NULL;
+	b0 = rd(tick) & (TSB_BUCKET_SIZE - 1);
+	i = b0;
+	do {
+		if ((bucket[i].tte_data & TD_V) == 0) {
+			tp = &bucket[i];
+			break;
+		}
+		if (tp == NULL) {
+			if ((bucket[i].tte_data & TD_REF) == 0)
+				tp = &bucket[i];
+			else if (rtp == NULL)
+				rtp = &bucket[i];
+		}
+	} while ((i = (i + 1) & (TSB_BUCKET_SIZE - 1)) != b0);
+
+	if (tp == NULL)
+		tp = rtp;
+	if ((tp->tte_data & TD_V) != 0) {
+		PMAP_STATS_INC(tsb_nrepl);
+		ova = TTE_GET_VA(tp);
+		pmap_remove_tte(pm, NULL, tp, ova);
+		tlb_page_demap(pm, ova);
+	}
+
+enter:
+	if ((m->flags & PG_FICTITIOUS) == 0) {
+		data |= TD_CP;
+		if ((m->oflags & VPO_UNMANAGED) == 0) {
+			pm->pm_stats.resident_count++;
+			data |= TD_PV;
+		}
+		if (pmap_cache_enter(m, va) != 0)
+			data |= TD_CV;
+		TAILQ_INSERT_TAIL(&m->md.tte_list, tp, tte_link);
+	} else
+		data |= TD_FAKE | TD_E;
+
+	tp->tte_vpn = TV_VPN(va, sz);
+	tp->tte_data = data;
+
+	return (tp);
+}
+
+/*
+ * Traverse the tsb of a pmap, calling the callback function for any tte entry
+ * that has a virtual address between start and end. If this function returns 0,
+ * tsb_foreach() terminates.
+ * This is used by pmap_remove(), pmap_protect(), and pmap_copy() in the case
+ * that the number of pages in the range given to them reaches the
+ * dimensions of the tsb size as an optimization.
+ */
+void
+tsb_foreach(pmap_t pm1, pmap_t pm2, vm_offset_t start, vm_offset_t end,
+    tsb_callback_t *callback)
+{
+	vm_offset_t va;
+	struct tte *tp;
+	struct tte *tsbp;
+	uintptr_t i;
+	uintptr_t n;
+
+	PMAP_STATS_INC(tsb_nforeach);
+	if (pm1 == kernel_pmap) {
+		tsbp = tsb_kernel;
+		n = tsb_kernel_size / sizeof(struct tte);
+	} else {
+		tsbp = pm1->pm_tsb;
+		n = TSB_SIZE;
+	}
+	for (i = 0; i < n; i++) {
+		tp = &tsbp[i];
+		if ((tp->tte_data & TD_V) != 0) {
+			va = TTE_GET_VA(tp);
+			if (va >= start && va < end) {
+				if (!callback(pm1, pm2, tp, va))
+					break;
+			}
+		}
+	}
+}


Property changes on: trunk/sys/sparc64/sparc64/tsb.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/uio_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/uio_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/uio_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,140 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Alan L. Cox <alc at cs.rice.edu>
+ * Copyright (c) 1982, 1986, 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, 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. 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.
+ *
+ *	@(#)kern_subr.c	8.3 (Berkeley) 1/21/94
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/uio_machdep.c 266312 2014-05-17 13:59:11Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/sf_buf.h>
+#include <sys/uio.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+#include <vm/vm_param.h>
+
+#include <machine/cache.h>
+#include <machine/tlb.h>
+
+/*
+ * Implement uiomove(9) from physical memory using a combination
+ * of the direct mapping and sf_bufs to reduce the creation and
+ * destruction of ephemeral mappings.
+ */
+int
+uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
+{
+	struct sf_buf *sf;
+	struct thread *td = curthread;
+	struct iovec *iov;
+	void *cp;
+	vm_offset_t page_offset;
+	vm_paddr_t pa;
+	vm_page_t m;
+	size_t cnt;
+	int error = 0;
+	int save = 0;
+
+	KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE,
+	    ("uiomove_fromphys: mode"));
+	KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread,
+	    ("uiomove_fromphys proc"));
+	save = td->td_pflags & TDP_DEADLKTREAT;
+	td->td_pflags |= TDP_DEADLKTREAT;
+	while (n > 0 && uio->uio_resid) {
+		iov = uio->uio_iov;
+		cnt = iov->iov_len;
+		if (cnt == 0) {
+			uio->uio_iov++;
+			uio->uio_iovcnt--;
+			continue;
+		}
+		if (cnt > n)
+			cnt = n;
+		page_offset = offset & PAGE_MASK;
+		cnt = ulmin(cnt, PAGE_SIZE - page_offset);
+		m = ma[offset >> PAGE_SHIFT];
+		pa = VM_PAGE_TO_PHYS(m);
+		if (dcache_color_ignore == 0 &&
+		    m->md.color != DCACHE_COLOR(pa)) {
+			sf = sf_buf_alloc(m, 0);
+			cp = (char *)sf_buf_kva(sf) + page_offset;
+		} else {
+			sf = NULL;
+			cp = (char *)TLB_PHYS_TO_DIRECT(pa) + page_offset;
+		}
+		switch (uio->uio_segflg) {
+		case UIO_USERSPACE:
+			maybe_yield();
+			if (uio->uio_rw == UIO_READ)
+				error = copyout(cp, iov->iov_base, cnt);
+			else
+				error = copyin(iov->iov_base, cp, cnt);
+			if (error) {
+				if (sf != NULL)
+					sf_buf_free(sf);
+				goto out;
+			}
+			break;
+		case UIO_SYSSPACE:
+			if (uio->uio_rw == UIO_READ)
+				bcopy(cp, iov->iov_base, cnt);
+			else
+				bcopy(iov->iov_base, cp, cnt);
+			break;
+		case UIO_NOCOPY:
+			break;
+		}
+		if (sf != NULL)
+			sf_buf_free(sf);
+		iov->iov_base = (char *)iov->iov_base + cnt;
+		iov->iov_len -= cnt;
+		uio->uio_resid -= cnt;
+		uio->uio_offset += cnt;
+		offset += cnt;
+		n -= cnt;
+	}
+out:
+	if (save == 0)
+		td->td_pflags &= ~TDP_DEADLKTREAT;
+	return (error);
+}


Property changes on: trunk/sys/sparc64/sparc64/uio_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/upa.c
===================================================================
--- trunk/sys/sparc64/sparc64/upa.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/upa.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,596 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/upa.c 227848 2011-11-22 21:55:40Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/bus_common.h>
+#include <machine/intr_machdep.h>
+#include <machine/resource.h>
+
+#define	UPA_NREG	3
+
+#define	UPA_CFG		0
+#define	UPA_IMR1	1
+#define	UPA_IMR2	2
+
+/* UPA_CFG bank */
+#define	UPA_CFG_UPA0			0x00	/* UPA0 config register */
+#define	UPA_CFG_UPA1			0x08	/* UPA1 config register */
+#define	UPA_CFG_IF			0x10	/* interface config register */
+#define	 UPA_CFG_IF_RST			0x00
+#define	 UPA_CFG_IF_POK_RST		0x02
+#define	 UPA_CFG_IF_POK			0x03
+#define	UPA_CFG_ESTAR			0x18	/* Estar config register */
+#define	 UPA_CFG_ESTAR_SPEED_FULL	0x01
+#define	 UPA_CFG_ESTAR_SPEED_1_2	0x02
+#define	 UPA_CFG_ESTAR_SPEED_1_64	0x40
+
+#define	UPA_INO_BASE			0x2a
+#define	UPA_INO_MAX			0x2b
+
+struct upa_regs {
+	uint64_t	phys;
+	uint64_t	size;
+};
+
+struct upa_ranges {
+	uint64_t	child;
+	uint64_t	parent;
+	uint64_t	size;
+};
+
+struct upa_devinfo {
+	struct ofw_bus_devinfo	udi_obdinfo;
+	struct resource_list	udi_rl;
+};
+
+struct upa_softc {
+	struct resource		*sc_res[UPA_NREG];
+	bus_space_tag_t		sc_bt[UPA_NREG];
+	bus_space_handle_t	sc_bh[UPA_NREG];
+
+	uint32_t		sc_ign;
+
+	int			sc_nrange;
+	struct upa_ranges	*sc_ranges;
+};
+
+#define	UPA_READ(sc, reg, off) \
+	bus_space_read_8((sc)->sc_bt[(reg)], (sc)->sc_bh[(reg)], (off))
+#define	UPA_WRITE(sc, reg, off, val) \
+	bus_space_write_8((sc)->sc_bt[(reg)], (sc)->sc_bh[(reg)], (off), (val))
+
+static device_probe_t upa_probe;
+static device_attach_t upa_attach;
+static bus_print_child_t upa_print_child;
+static bus_probe_nomatch_t upa_probe_nomatch;
+static bus_alloc_resource_t upa_alloc_resource;
+static bus_adjust_resource_t upa_adjust_resource;
+static bus_setup_intr_t upa_setup_intr;
+static bus_get_resource_list_t upa_get_resource_list;
+static ofw_bus_get_devinfo_t upa_get_devinfo;
+
+static void upa_intr_enable(void *);
+static void upa_intr_disable(void *);
+static void upa_intr_assign(void *);
+static struct upa_devinfo *upa_setup_dinfo(device_t, struct upa_softc *,
+    phandle_t, uint32_t);
+static void upa_destroy_dinfo(struct upa_devinfo *);
+static int upa_print_res(struct upa_devinfo *);
+
+static device_method_t upa_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		upa_probe),
+	DEVMETHOD(device_attach,	upa_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	upa_print_child),
+	DEVMETHOD(bus_probe_nomatch,	upa_probe_nomatch),
+	DEVMETHOD(bus_read_ivar,	bus_generic_read_ivar),
+	DEVMETHOD(bus_write_ivar,	bus_generic_write_ivar),
+	DEVMETHOD(bus_alloc_resource,	upa_alloc_resource),
+	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	upa_adjust_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_rl_release_resource),
+	DEVMETHOD(bus_setup_intr,	upa_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	DEVMETHOD(bus_get_resource_list, upa_get_resource_list),
+	DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	upa_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	DEVMETHOD_END
+};
+
+static devclass_t upa_devclass;
+
+DEFINE_CLASS_0(upa, upa_driver, upa_methods, sizeof(struct upa_softc));
+EARLY_DRIVER_MODULE(upa, nexus, upa_driver, upa_devclass, 0, 0, BUS_PASS_BUS);
+
+static const struct intr_controller upa_ic = {
+	upa_intr_enable,
+	upa_intr_disable,
+	upa_intr_assign,
+	/* The interrupts are pulse type and thus automatically cleared. */
+	NULL
+};
+
+struct upa_icarg {
+	struct upa_softc	*uica_sc;
+	u_int			uica_imr;
+};
+
+static int
+upa_probe(device_t dev)
+{
+	const char* compat;
+
+	compat = ofw_bus_get_compat(dev);
+	if (compat != NULL && strcmp(ofw_bus_get_name(dev), "upa") == 0 &&
+	    strcmp(compat, "upa64s") == 0) {
+		device_set_desc(dev, "UPA bridge");
+		return (BUS_PROBE_DEFAULT);
+	}
+	return (ENXIO);
+}
+
+static int
+upa_attach(device_t dev)
+{
+	struct upa_devinfo *udi;
+	struct upa_icarg *uica;
+	struct upa_softc *sc;
+	phandle_t child, node;
+	device_t cdev;
+	uint32_t portid;
+	int i, imr, j, rid;
+#if 1
+	device_t *children, schizo;
+	u_long scount, sstart, ucount, ustart;
+	int nchildren;
+#endif
+
+	sc = device_get_softc(dev);
+	node = ofw_bus_get_node(dev);
+	for (i = UPA_CFG; i <= UPA_IMR2; i++) {
+		rid = i;
+		/*
+		 * The UPA_IMR{1,2} resources are shared with that of the
+		 * Schizo PCI bus B CSR bank.
+		 */
+#if 0
+		sc->sc_res[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+		    &rid, ((i == UPA_IMR1 || i == UPA_IMR2) ? RF_SHAREABLE :
+		    0) | RF_ACTIVE);
+		if (sc->sc_res[i] == NULL) {
+			device_printf(dev,
+			    "could not allocate resource %d\n", i);
+			goto fail;
+		}
+		sc->sc_bt[i] = rman_get_bustag(sc->sc_res[i]);
+		sc->sc_bh[i] = rman_get_bushandle(sc->sc_res[i]);
+#else
+		/*
+		 * Workaround for the fact that rman(9) only allows to
+		 * share resources of the same size.
+		 */
+		if (i == UPA_IMR1 || i == UPA_IMR2) {
+			if (bus_get_resource(dev, SYS_RES_MEMORY, i, &ustart,
+			    &ucount) != 0) {
+				device_printf(dev,
+				    "could not determine UPA resource\n");
+				goto fail;
+			}
+			if (device_get_children(device_get_parent(dev),
+			    &children, &nchildren) != 0) {
+				device_printf(dev, "could not get children\n");
+				goto fail;
+			}
+			schizo = NULL;
+			for (j = 0; j < nchildren; j++) {
+				if (ofw_bus_get_type(children[j]) != NULL &&
+				    strcmp(ofw_bus_get_type(children[j]),
+				    "pci") == 0 &&
+				    ofw_bus_get_compat(children[j]) != NULL &&
+				    strcmp(ofw_bus_get_compat(children[j]),
+				    "pci108e,8001") == 0 &&
+				    ((bus_get_resource_start(children[j],
+				    SYS_RES_MEMORY, 0) >> 20) & 1) == 1) {
+					schizo = children[j];
+					break;
+				}
+			}
+			free(children, M_TEMP);
+			if (schizo == NULL) {
+				device_printf(dev, "could not find Schizo\n");
+				goto fail;
+			}
+			if (bus_get_resource(schizo, SYS_RES_MEMORY, 0,
+			    &sstart, &scount) != 0) {
+				device_printf(dev,
+				    "could not determine Schizo resource\n");
+				goto fail;
+			}
+			sc->sc_res[i] = bus_alloc_resource(dev, SYS_RES_MEMORY,
+			    &rid, sstart, sstart + scount - 1, scount,
+			    RF_SHAREABLE | RF_ACTIVE);
+		} else
+			sc->sc_res[i] = bus_alloc_resource_any(dev,
+			    SYS_RES_MEMORY, &rid, RF_ACTIVE);
+		if (sc->sc_res[i] == NULL) {
+			device_printf(dev,
+			    "could not allocate resource %d\n", i);
+			goto fail;
+		}
+		sc->sc_bt[i] = rman_get_bustag(sc->sc_res[i]);
+		sc->sc_bh[i] = rman_get_bushandle(sc->sc_res[i]);
+		if (i == UPA_IMR1 || i == UPA_IMR2)
+			bus_space_subregion(sc->sc_bt[i], sc->sc_bh[i],
+			    ustart - sstart, ucount, &sc->sc_bh[i]);
+#endif
+	}
+
+	if (OF_getprop(node, "portid", &sc->sc_ign, sizeof(sc->sc_ign)) == -1) {
+		device_printf(dev, "could not determine IGN\n");
+		goto fail;
+	}
+
+	sc->sc_nrange = OF_getprop_alloc(node, "ranges", sizeof(*sc->sc_ranges),
+	    (void **)&sc->sc_ranges);
+	if (sc->sc_nrange == -1) {
+		device_printf(dev, "could not determine ranges\n");
+		goto fail;
+	}
+
+	/*
+	 * Hunt through all the interrupt mapping regs and register our
+	 * interrupt controller for the corresponding interrupt vectors.
+	 * We do this early in order to be able to catch stray interrupts.
+	 */
+	for (i = UPA_INO_BASE; i <= UPA_INO_MAX; i++) {
+		imr = 0;
+		for (j = UPA_IMR1; j <= UPA_IMR2; j++) {
+			if (INTVEC(UPA_READ(sc, j, 0x0)) ==
+			    INTMAP_VEC(sc->sc_ign, i)) {
+				imr = j;
+				break;
+			}
+		}
+		if (imr == 0)
+			continue;
+		uica = malloc(sizeof(*uica), M_DEVBUF, M_NOWAIT);
+		if (uica == NULL)
+			panic("%s: could not allocate interrupt controller "
+			    "argument", __func__);
+		uica->uica_sc = sc;
+		uica->uica_imr = imr;
+#ifdef UPA_DEBUG
+		device_printf(dev, "intr map (INO %d) IMR%d: %#lx\n",
+		    i, imr, (u_long)UPA_READ(sc, imr, 0x0));
+#endif
+		j = intr_controller_register(INTMAP_VEC(sc->sc_ign, i),
+		    &upa_ic, uica);
+		if (j != 0)
+			device_printf(dev, "could not register interrupt "
+			    "controller for INO %d (%d)\n", i, j);
+	}
+
+	/* Make sure the power level is appropriate for normal operation. */
+	if (UPA_READ(sc, UPA_CFG, UPA_CFG_IF) != UPA_CFG_IF_POK) {
+		if (bootverbose)
+			device_printf(dev, "applying power\n");
+		UPA_WRITE(sc, UPA_CFG, UPA_CFG_ESTAR, UPA_CFG_ESTAR_SPEED_1_2);
+		UPA_WRITE(sc, UPA_CFG, UPA_CFG_ESTAR, UPA_CFG_ESTAR_SPEED_FULL);
+		(void)UPA_READ(sc, UPA_CFG, UPA_CFG_ESTAR);
+		UPA_WRITE(sc, UPA_CFG, UPA_CFG_IF, UPA_CFG_IF_POK_RST);
+		(void)UPA_READ(sc, UPA_CFG, UPA_CFG_IF);
+		DELAY(20000);
+		UPA_WRITE(sc, UPA_CFG, UPA_CFG_IF, UPA_CFG_IF_POK);
+		(void)UPA_READ(sc, UPA_CFG, UPA_CFG_IF);
+	}
+
+	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+		/*
+		 * The `upa-portid' properties of the children are used as
+		 * index for the interrupt mapping registers.
+		 * The `upa-portid' properties are also used to make up the
+		 * INOs of the children as the values contained in their
+		 * `interrupts' properties are bogus.
+		 */
+		if (OF_getprop(child, "upa-portid", &portid,
+		    sizeof(portid)) == -1) {
+			device_printf(dev,
+			    "could not determine upa-portid of child 0x%lx\n",
+			    (unsigned long)child);
+			continue;
+		}
+		if (portid > 1) {
+			device_printf(dev,
+			    "upa-portid %d of child 0x%lx invalid\n", portid,
+			    (unsigned long)child);
+			continue;
+		}
+		if ((udi = upa_setup_dinfo(dev, sc, child, portid)) == NULL)
+			continue;
+		if ((cdev = device_add_child(dev, NULL, -1)) == NULL) {
+			device_printf(dev, "<%s>: device_add_child failed\n",
+			    udi->udi_obdinfo.obd_name);
+			upa_destroy_dinfo(udi);
+			continue;
+		}
+		device_set_ivars(cdev, udi);
+	}
+
+	return (bus_generic_attach(dev));
+
+ fail:
+	for (i = UPA_CFG; i <= UPA_IMR2 && sc->sc_res[i] != NULL; i++)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    rman_get_rid(sc->sc_res[i]), sc->sc_res[i]);
+	return (ENXIO);
+}
+
+static int
+upa_print_child(device_t dev, device_t child)
+{
+	int rv;
+
+	rv = bus_print_child_header(dev, child);
+	rv += upa_print_res(device_get_ivars(child));
+	rv += bus_print_child_footer(dev, child);
+	return (rv);
+}
+
+static void
+upa_probe_nomatch(device_t dev, device_t child)
+{
+	const char *type;
+
+	device_printf(dev, "<%s>", ofw_bus_get_name(child));
+	upa_print_res(device_get_ivars(child));
+	type = ofw_bus_get_type(child);
+	printf(" type %s (no driver attached)\n",
+	    type != NULL ? type : "unknown");
+}
+
+static struct resource *
+upa_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct resource_list *rl;
+	struct resource_list_entry *rle;
+	struct upa_softc *sc;
+	struct resource *rv;
+	bus_addr_t cend, cstart;
+	int i, isdefault, passthrough;
+
+	isdefault = (start == 0UL && end == ~0UL);
+	passthrough = (device_get_parent(child) != dev);
+	sc = device_get_softc(dev);
+	rl = BUS_GET_RESOURCE_LIST(dev, child);
+	rle = NULL;
+	switch (type) {
+	case SYS_RES_IRQ:
+		return (resource_list_alloc(rl, dev, child, type, rid, start,
+		    end, count, flags));
+	case SYS_RES_MEMORY:
+		if (!passthrough) {
+			rle = resource_list_find(rl, type, *rid);
+			if (rle == NULL)
+				return (NULL);
+			if (rle->res != NULL)
+				panic("%s: resource entry is busy", __func__);
+			if (isdefault) {
+				start = rle->start;
+				count = ulmax(count, rle->count);
+				end = ulmax(rle->end, start + count - 1);
+			}
+		}
+		for (i = 0; i < sc->sc_nrange; i++) {
+			cstart = sc->sc_ranges[i].child;
+			cend = cstart + sc->sc_ranges[i].size - 1;
+			if (start < cstart || start > cend)
+				continue;
+			if (end < cstart || end > cend)
+				return (NULL);
+			start += sc->sc_ranges[i].parent - cstart;
+			end += sc->sc_ranges[i].parent - cstart;
+			rv = bus_generic_alloc_resource(dev, child, type, rid,
+			    start, end, count, flags);
+			if (!passthrough)
+				rle->res = rv;
+			return (rv);
+		}
+		/* FALLTHROUGH */
+	default:
+		return (NULL);
+	}
+}
+
+static void
+upa_intr_enable(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct upa_icarg *uica = iv->iv_icarg;
+
+	UPA_WRITE(uica->uica_sc, uica->uica_imr, 0x0,
+	    INTMAP_ENABLE(iv->iv_vec, iv->iv_mid));
+	(void)UPA_READ(uica->uica_sc, uica->uica_imr, 0x0);
+}
+
+static void
+upa_intr_disable(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct upa_icarg *uica = iv->iv_icarg;
+
+	UPA_WRITE(uica->uica_sc, uica->uica_imr, 0x0, iv->iv_vec);
+	(void)UPA_READ(uica->uica_sc, uica->uica_imr, 0x0);
+}
+
+static void
+upa_intr_assign(void *arg)
+{
+	struct intr_vector *iv = arg;
+	struct upa_icarg *uica = iv->iv_icarg;
+
+	UPA_WRITE(uica->uica_sc, uica->uica_imr, 0x0, INTMAP_TID(
+	    UPA_READ(uica->uica_sc, uica->uica_imr, 0x0), iv->iv_mid));
+	(void)UPA_READ(uica->uica_sc, uica->uica_imr, 0x0);
+}
+
+static int
+upa_setup_intr(device_t dev, device_t child, struct resource *ires, int flags,
+    driver_filter_t *filt, driver_intr_t *func, void *arg, void **cookiep)
+{
+	struct upa_softc *sc;
+	u_long vec;
+
+	sc = device_get_softc(dev);
+	/*
+	 * Make sure the vector is fully specified and we registered
+	 * our interrupt controller for it.
+	 */
+	vec = rman_get_start(ires);
+	if (INTIGN(vec) != sc->sc_ign || intr_vectors[vec].iv_ic != &upa_ic) {
+		device_printf(dev, "invalid interrupt vector 0x%lx\n", vec);
+		return (EINVAL);
+	}
+	return (bus_generic_setup_intr(dev, child, ires, flags, filt, func,
+	    arg, cookiep));
+}
+
+static int
+upa_adjust_resource(device_t bus __unused, device_t child __unused,
+    int type __unused, struct resource *r __unused, u_long start __unused,
+    u_long end __unused)
+{
+
+	return (ENXIO);
+}
+
+static struct resource_list *
+upa_get_resource_list(device_t dev, device_t child)
+{
+	struct upa_devinfo *udi;
+
+	udi = device_get_ivars(child);
+	return (&udi->udi_rl);
+}
+
+static const struct ofw_bus_devinfo *
+upa_get_devinfo(device_t dev, device_t child)
+{
+	struct upa_devinfo *udi;
+
+	udi = device_get_ivars(child);
+	return (&udi->udi_obdinfo);
+}
+
+static struct upa_devinfo *
+upa_setup_dinfo(device_t dev, struct upa_softc *sc, phandle_t node,
+    uint32_t portid)
+{
+	struct upa_devinfo *udi;
+	struct upa_regs *reg;
+	uint32_t intr;
+	int i, nreg;
+
+	udi = malloc(sizeof(*udi), M_DEVBUF, M_WAITOK | M_ZERO);
+	if (ofw_bus_gen_setup_devinfo(&udi->udi_obdinfo, node) != 0) {
+		free(udi, M_DEVBUF);
+		return (NULL);
+	}
+	resource_list_init(&udi->udi_rl);
+
+	nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
+	if (nreg == -1) {
+		device_printf(dev, "<%s>: incomplete\n",
+		    udi->udi_obdinfo.obd_name);
+		goto fail;
+	}
+	for (i = 0; i < nreg; i++)
+		resource_list_add(&udi->udi_rl, SYS_RES_MEMORY, i, reg[i].phys,
+		    reg[i].phys + reg[i].size - 1, reg[i].size);
+	free(reg, M_OFWPROP);
+
+	intr = INTMAP_VEC(sc->sc_ign, (UPA_INO_BASE + portid));
+	resource_list_add(&udi->udi_rl, SYS_RES_IRQ, 0, intr, intr, 1);
+
+	return (udi);
+
+ fail:
+	upa_destroy_dinfo(udi);
+	return (NULL);
+}
+
+static void
+upa_destroy_dinfo(struct upa_devinfo *dinfo)
+{
+
+	resource_list_free(&dinfo->udi_rl);
+	ofw_bus_gen_destroy_devinfo(&dinfo->udi_obdinfo);
+	free(dinfo, M_DEVBUF);
+}
+
+static int
+upa_print_res(struct upa_devinfo *udi)
+{
+	int rv;
+
+	rv = 0;
+	rv += resource_list_print_type(&udi->udi_rl, "mem", SYS_RES_MEMORY,
+	    "%#lx");
+	rv += resource_list_print_type(&udi->udi_rl, "irq", SYS_RES_IRQ,
+	    "%ld");
+	return (rv);
+}


Property changes on: trunk/sys/sparc64/sparc64/upa.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/vm_machdep.c
===================================================================
--- trunk/sys/sparc64/sparc64/vm_machdep.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/vm_machdep.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,547 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1982, 1986 The Regents of the University of California.
+ * Copyright (c) 1989, 1990 William Jolitz
+ * Copyright (c) 1994 John Dyson
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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.
+ *
+ * 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.
+ * 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: @(#)vm_machdep.c	7.3 (Berkeley) 5/13/91
+ *	Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
+ *	from: FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.167 2001/07/12
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/vm_machdep.c 301428 2016-06-05 07:34:10Z dchagin $");
+
+#include "opt_pmap.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/buf.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/sysent.h>
+#include <sys/sf_buf.h>
+#include <sys/sched.h>
+#include <sys/sysctl.h>
+#include <sys/unistd.h>
+#include <sys/vmmeter.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
+#include <vm/vm_param.h>
+#include <vm/uma.h>
+#include <vm/uma_int.h>
+
+#include <machine/cache.h>
+#include <machine/cpu.h>
+#include <machine/fp.h>
+#include <machine/frame.h>
+#include <machine/fsr.h>
+#include <machine/md_var.h>
+#include <machine/ofw_machdep.h>
+#include <machine/ofw_mem.h>
+#include <machine/pcb.h>
+#include <machine/tlb.h>
+#include <machine/tstate.h>
+
+#ifndef NSFBUFS
+#define	NSFBUFS		(512 + maxusers * 16)
+#endif
+
+static int nsfbufs;
+static int nsfbufspeak;
+static int nsfbufsused;
+
+SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufs, CTLFLAG_RDTUN, &nsfbufs, 0,
+    "Maximum number of sendfile(2) sf_bufs available");
+SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufspeak, CTLFLAG_RD, &nsfbufspeak, 0,
+    "Number of sendfile(2) sf_bufs at peak usage");
+SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufsused, CTLFLAG_RD, &nsfbufsused, 0,
+    "Number of sendfile(2) sf_bufs in use");
+
+static void	sf_buf_init(void *arg);
+SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL);
+
+/*
+ * Expanded sf_freelist head.  Really an SLIST_HEAD() in disguise, with the
+ * sf_freelist head with the sf_lock mutex.
+ */
+static struct {
+	SLIST_HEAD(, sf_buf) sf_head;
+	struct mtx sf_lock;
+} sf_freelist;
+
+static u_int	sf_buf_alloc_want;
+
+PMAP_STATS_VAR(uma_nsmall_alloc);
+PMAP_STATS_VAR(uma_nsmall_alloc_oc);
+PMAP_STATS_VAR(uma_nsmall_free);
+
+void
+cpu_exit(struct thread *td)
+{
+	struct proc *p;
+
+	p = td->td_proc;
+	p->p_md.md_sigtramp = NULL;
+	if (p->p_md.md_utrap != NULL) {
+		utrap_free(p->p_md.md_utrap);
+		p->p_md.md_utrap = NULL;
+	}
+}
+
+void
+cpu_thread_exit(struct thread *td)
+{
+
+}
+
+void
+cpu_thread_clean(struct thread *td)
+{
+
+}
+
+void
+cpu_thread_alloc(struct thread *td)
+{
+	struct pcb *pcb;
+
+	pcb = (struct pcb *)((td->td_kstack + td->td_kstack_pages * PAGE_SIZE -
+	    sizeof(struct pcb)) & ~0x3fUL);
+	pcb->pcb_nsaved = 0;
+	td->td_frame = (struct trapframe *)pcb - 1;
+	td->td_pcb = pcb;
+}
+
+void
+cpu_thread_free(struct thread *td)
+{
+
+}
+
+void
+cpu_thread_swapin(struct thread *td)
+{
+
+}
+
+void
+cpu_thread_swapout(struct thread *td)
+{
+
+}
+
+void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+
+	switch (error) {
+	case 0:
+		td->td_frame->tf_out[0] = td->td_retval[0];
+		td->td_frame->tf_out[1] = td->td_retval[1];
+		td->td_frame->tf_tstate &= ~TSTATE_XCC_C;
+		break;
+
+	case ERESTART:
+		/*
+		 * Undo the tpc advancement we have done on syscall
+		 * enter, we want to reexecute the system call.
+		 */
+		td->td_frame->tf_tpc = td->td_pcb->pcb_tpc;
+		td->td_frame->tf_tnpc -= 4;
+		break;
+
+	case EJUSTRETURN:
+		break;
+
+	default:
+		td->td_frame->tf_out[0] = SV_ABI_ERRNO(td->td_proc, error);
+		td->td_frame->tf_tstate |= TSTATE_XCC_C;
+		break;
+	}
+}
+
+void
+cpu_set_upcall(struct thread *td, struct thread *td0)
+{
+	struct trapframe *tf;
+	struct frame *fr;
+	struct pcb *pcb;
+
+	bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe));
+
+	pcb = td->td_pcb;
+	tf = td->td_frame;
+	fr = (struct frame *)tf - 1;
+	fr->fr_local[0] = (u_long)fork_return;
+	fr->fr_local[1] = (u_long)td;
+	fr->fr_local[2] = (u_long)tf;
+	pcb->pcb_pc = (u_long)fork_trampoline - 8;
+	pcb->pcb_sp = (u_long)fr - SPOFF;
+
+	/* Setup to release the spin count in fork_exit(). */
+	td->td_md.md_spinlock_count = 1;
+	td->td_md.md_saved_pil = 0;
+}
+
+void
+cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg,
+    stack_t *stack)
+{
+	struct trapframe *tf;
+	uint64_t sp;
+
+	if (td == curthread)
+		flushw();
+	tf = td->td_frame;
+	sp = (uint64_t)stack->ss_sp + stack->ss_size;
+	tf->tf_out[0] = (uint64_t)arg;
+	tf->tf_out[6] = sp - SPOFF - sizeof(struct frame);
+	tf->tf_tpc = (uint64_t)entry;
+	tf->tf_tnpc = tf->tf_tpc + 4;
+
+	td->td_retval[0] = tf->tf_out[0];
+	td->td_retval[1] = tf->tf_out[1];
+}
+
+int
+cpu_set_user_tls(struct thread *td, void *tls_base)
+{
+
+	if (td == curthread)
+		flushw();
+	td->td_frame->tf_global[7] = (uint64_t)tls_base;
+	return (0);
+}
+
+/*
+ * Finish a fork operation, with process p2 nearly set up.
+ * Copy and update the pcb, set up the stack so that the child
+ * ready to run and return to user mode.
+ */
+void
+cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
+{
+	struct trapframe *tf;
+	struct frame *fp;
+	struct pcb *pcb1;
+	struct pcb *pcb2;
+	vm_offset_t sp;
+	int error;
+	int i;
+
+	KASSERT(td1 == curthread || td1 == &thread0,
+	    ("cpu_fork: p1 not curproc and not proc0"));
+
+	if ((flags & RFPROC) == 0)
+		return;
+
+	p2->p_md.md_sigtramp = td1->td_proc->p_md.md_sigtramp;
+	p2->p_md.md_utrap = utrap_hold(td1->td_proc->p_md.md_utrap);
+
+	/* The pcb must be aligned on a 64-byte boundary. */
+	pcb1 = td1->td_pcb;
+	pcb2 = (struct pcb *)((td2->td_kstack + td2->td_kstack_pages *
+	    PAGE_SIZE - sizeof(struct pcb)) & ~0x3fUL);
+	td2->td_pcb = pcb2;
+
+	/*
+	 * Ensure that p1's pcb is up to date.
+	 */
+	critical_enter();
+	if ((td1->td_frame->tf_fprs & FPRS_FEF) != 0)
+		savefpctx(pcb1->pcb_ufp);
+	critical_exit();
+	/* Make sure the copied windows are spilled. */
+	flushw();
+	/* Copy the pcb (this will copy the windows saved in the pcb, too). */
+	bcopy(pcb1, pcb2, sizeof(*pcb1));
+
+	/*
+	 * If we're creating a new user process and we're sharing the address
+	 * space, the parent's top most frame must be saved in the pcb.  The
+	 * child will pop the frame when it returns to user mode, and may
+	 * overwrite it with its own data causing much suffering for the
+	 * parent.  We check if its already in the pcb, and if not copy it
+	 * in.  Its unlikely that the copyin will fail, but if so there's not
+	 * much we can do.  The parent will likely crash soon anyway in that
+	 * case.
+	 */
+	if ((flags & RFMEM) != 0 && td1 != &thread0) {
+		sp = td1->td_frame->tf_sp;
+		for (i = 0; i < pcb1->pcb_nsaved; i++) {
+			if (pcb1->pcb_rwsp[i] == sp)
+				break;
+		}
+		if (i == pcb1->pcb_nsaved) {
+			error = copyin((caddr_t)sp + SPOFF, &pcb1->pcb_rw[i],
+			    sizeof(struct rwindow));
+			if (error == 0) {
+				pcb1->pcb_rwsp[i] = sp;
+				pcb1->pcb_nsaved++;
+			}
+		}
+	}
+
+	/*
+	 * Create a new fresh stack for the new process.
+	 * Copy the trap frame for the return to user mode as if from a
+	 * syscall.  This copies most of the user mode register values.
+	 */
+	tf = (struct trapframe *)pcb2 - 1;
+	bcopy(td1->td_frame, tf, sizeof(*tf));
+
+	tf->tf_out[0] = 0;			/* Child returns zero */
+	tf->tf_out[1] = 0;
+	tf->tf_tstate &= ~TSTATE_XCC_C;		/* success */
+	tf->tf_fprs = 0;
+
+	td2->td_frame = tf;
+	fp = (struct frame *)tf - 1;
+	fp->fr_local[0] = (u_long)fork_return;
+	fp->fr_local[1] = (u_long)td2;
+	fp->fr_local[2] = (u_long)tf;
+	/* Terminate stack traces at this frame. */
+	fp->fr_pc = fp->fr_fp = 0;
+	pcb2->pcb_sp = (u_long)fp - SPOFF;
+	pcb2->pcb_pc = (u_long)fork_trampoline - 8;
+
+	/* Setup to release the spin count in fork_exit(). */
+	td2->td_md.md_spinlock_count = 1;
+	td2->td_md.md_saved_pil = 0;
+
+	/*
+	 * Now, cpu_switch() can schedule the new process.
+	 */
+}
+
+void
+cpu_reset(void)
+{
+	static char bspec[64] = "";
+	phandle_t chosen;
+	static struct {
+		cell_t	name;
+		cell_t	nargs;
+		cell_t	nreturns;
+		cell_t	bootspec;
+	} args = {
+		(cell_t)"boot",
+		1,
+		0,
+		(cell_t)bspec
+	};
+
+	if ((chosen = OF_finddevice("/chosen")) != -1) {
+		if (OF_getprop(chosen, "bootpath", bspec, sizeof(bspec)) == -1)
+			bspec[0] = '\0';
+		bspec[sizeof(bspec) - 1] = '\0';
+	}
+
+	cpu_shutdown(&args);
+}
+
+/*
+ * Intercept the return address from a freshly forked process that has NOT
+ * been scheduled yet.
+ *
+ * This is needed to make kernel threads stay in kernel mode.
+ */
+void
+cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg)
+{
+	struct frame *fp;
+	struct pcb *pcb;
+
+	pcb = td->td_pcb;
+	fp = (struct frame *)(pcb->pcb_sp + SPOFF);
+	fp->fr_local[0] = (u_long)func;
+	fp->fr_local[1] = (u_long)arg;
+}
+
+int
+is_physical_memory(vm_paddr_t addr)
+{
+	struct ofw_mem_region *mr;
+
+	for (mr = sparc64_memreg; mr < sparc64_memreg + sparc64_nmemreg; mr++)
+		if (addr >= mr->mr_start && addr < mr->mr_start + mr->mr_size)
+			return (1);
+	return (0);
+}
+
+/*
+ * Allocate a pool of sf_bufs (sendfile(2) or "super-fast" if you prefer. :-))
+ */
+static void
+sf_buf_init(void *arg)
+{
+	struct sf_buf *sf_bufs;
+	vm_offset_t sf_base;
+	int i;
+
+	nsfbufs = NSFBUFS;
+	TUNABLE_INT_FETCH("kern.ipc.nsfbufs", &nsfbufs);
+
+	mtx_init(&sf_freelist.sf_lock, "sf_bufs list lock", NULL, MTX_DEF);
+	SLIST_INIT(&sf_freelist.sf_head);
+	sf_base = kva_alloc(nsfbufs * PAGE_SIZE);
+	sf_bufs = malloc(nsfbufs * sizeof(struct sf_buf), M_TEMP,
+	    M_NOWAIT | M_ZERO);
+	for (i = 0; i < nsfbufs; i++) {
+		sf_bufs[i].kva = sf_base + i * PAGE_SIZE;
+		SLIST_INSERT_HEAD(&sf_freelist.sf_head, &sf_bufs[i], free_list);
+	}
+	sf_buf_alloc_want = 0;
+}
+
+/*
+ * Get an sf_buf from the freelist.  Will block if none are available.
+ */
+struct sf_buf *
+sf_buf_alloc(struct vm_page *m, int flags)
+{
+	struct sf_buf *sf;
+	int error;
+
+	mtx_lock(&sf_freelist.sf_lock);
+	while ((sf = SLIST_FIRST(&sf_freelist.sf_head)) == NULL) {
+		if (flags & SFB_NOWAIT)
+			break;
+		sf_buf_alloc_want++;
+		SFSTAT_INC(sf_allocwait);
+		error = msleep(&sf_freelist, &sf_freelist.sf_lock,
+		    (flags & SFB_CATCH) ? PCATCH | PVM : PVM, "sfbufa", 0);
+		sf_buf_alloc_want--;
+
+		/*
+		 * If we got a signal, don't risk going back to sleep.
+		 */
+		if (error)
+			break;
+	}
+	if (sf != NULL) {
+		SLIST_REMOVE_HEAD(&sf_freelist.sf_head, free_list);
+		sf->m = m;
+		nsfbufsused++;
+		nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
+		pmap_qenter(sf->kva, &sf->m, 1);
+	}
+	mtx_unlock(&sf_freelist.sf_lock);
+	return (sf);
+}
+
+/*
+ * Release resources back to the system.
+ */
+void
+sf_buf_free(struct sf_buf *sf)
+{
+
+	pmap_qremove(sf->kva, 1);
+	mtx_lock(&sf_freelist.sf_lock);
+	SLIST_INSERT_HEAD(&sf_freelist.sf_head, sf, free_list);
+	nsfbufsused--;
+	if (sf_buf_alloc_want > 0)
+		wakeup(&sf_freelist);
+	mtx_unlock(&sf_freelist.sf_lock);
+}
+
+void
+swi_vm(void *v)
+{
+
+	/* Nothing to do here - busdma bounce buffers are not implemented. */
+}
+
+void *
+uma_small_alloc(uma_zone_t zone, vm_size_t bytes, u_int8_t *flags, int wait)
+{
+	vm_paddr_t pa;
+	vm_page_t m;
+	int pflags;
+	void *va;
+
+	PMAP_STATS_INC(uma_nsmall_alloc);
+
+	*flags = UMA_SLAB_PRIV;
+	pflags = malloc2vm_flags(wait) | VM_ALLOC_WIRED;
+
+	for (;;) {
+		m = vm_page_alloc(NULL, 0, pflags | VM_ALLOC_NOOBJ);
+		if (m == NULL) {
+			if (wait & M_NOWAIT)
+				return (NULL);
+			else
+				VM_WAIT;
+		} else
+			break;
+	}
+
+	pa = VM_PAGE_TO_PHYS(m);
+	if (dcache_color_ignore == 0 && m->md.color != DCACHE_COLOR(pa)) {
+		KASSERT(m->md.colors[0] == 0 && m->md.colors[1] == 0,
+		    ("uma_small_alloc: free page %p still has mappings!", m));
+		PMAP_STATS_INC(uma_nsmall_alloc_oc);
+		m->md.color = DCACHE_COLOR(pa);
+		dcache_page_inval(pa);
+	}
+	va = (void *)TLB_PHYS_TO_DIRECT(pa);
+	if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0)
+		cpu_block_zero(va, PAGE_SIZE);
+	return (va);
+}
+
+void
+uma_small_free(void *mem, vm_size_t size, u_int8_t flags)
+{
+	vm_page_t m;
+
+	PMAP_STATS_INC(uma_nsmall_free);
+	m = PHYS_TO_VM_PAGE(TLB_DIRECT_TO_PHYS((vm_offset_t)mem));
+	m->wire_count--;
+	vm_page_free(m);
+	atomic_subtract_int(&cnt.v_wire_count, 1);
+}


Property changes on: trunk/sys/sparc64/sparc64/vm_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/sparc64/sparc64/zeus.c
===================================================================
--- trunk/sys/sparc64/sparc64/zeus.c	                        (rev 0)
+++ trunk/sys/sparc64/sparc64/zeus.c	2018-05-25 12:44:45 UTC (rev 9914)
@@ -0,0 +1,172 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 - 2011 Marius Strobl <marius at 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, 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/sparc64/sparc64/zeus.c 223719 2011-07-02 11:14:54Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/asi.h>
+#include <machine/cache.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/mcntl.h>
+#include <machine/lsu.h>
+#include <machine/tlb.h>
+#include <machine/tte.h>
+#include <machine/vmparam.h>
+
+#define	ZEUS_FTLB_ENTRIES	32
+#define	ZEUS_STLB_ENTRIES	2048
+
+/*
+ * CPU-specific initialization for Fujitsu Zeus CPUs
+ */
+void
+zeus_init(u_int cpu_impl)
+{
+	u_long val;
+
+	/* Ensure the TSB Extension Registers hold 0 as TSB_Base. */
+
+	stxa(AA_DMMU_TSB_PEXT_REG, ASI_DMMU, 0);
+	stxa(AA_IMMU_TSB_PEXT_REG, ASI_IMMU, 0);
+	membar(Sync);
+
+	stxa(AA_DMMU_TSB_SEXT_REG, ASI_DMMU, 0);
+	/*
+	 * NB: the secondary context was removed from the iMMU.
+	 */
+	membar(Sync);
+
+	stxa(AA_DMMU_TSB_NEXT_REG, ASI_DMMU, 0);
+	stxa(AA_IMMU_TSB_NEXT_REG, ASI_IMMU, 0);
+	membar(Sync);
+
+	val = ldxa(AA_MCNTL, ASI_MCNTL);
+	/* Ensure MCNTL_JPS1_TSBP is 0. */
+	val &= ~MCNTL_JPS1_TSBP;
+	/*
+	 * Ensure 4-Mbyte page entries are stored in the 1024-entry, 2-way set
+	 * associative TLB.
+	 */
+	val = (val & ~MCNTL_RMD_MASK) | MCNTL_RMD_1024;
+	stxa(AA_MCNTL, ASI_MCNTL, val);
+}
+
+/*
+ * Enable level 1 caches.
+ */
+void
+zeus_cache_enable(u_int cpu_impl)
+{
+	u_long lsu;
+
+	lsu = ldxa(0, ASI_LSU_CTL_REG);
+	stxa(0, ASI_LSU_CTL_REG, lsu | LSU_IC | LSU_DC);
+	flush(KERNBASE);
+}
+
+/*
+ * Flush all lines from the level 1 caches.
+ */
+void
+zeus_cache_flush(void)
+{
+
+	stxa_sync(0, ASI_FLUSH_L1I, 0);
+}
+
+/*
+ * Flush a physical page from the data cache.  Data cache consistency is
+ * maintained by hardware.
+ */
+void
+zeus_dcache_page_inval(vm_paddr_t spa __unused)
+{
+
+}
+
+/*
+ * Flush a physical page from the intsruction cache.  Instruction cache
+ * consistency is maintained by hardware.
+ */
+void
+zeus_icache_page_inval(vm_paddr_t pa __unused)
+{
+
+}
+
+/*
+ * Flush all non-locked mappings from the TLBs.
+ */
+void
+zeus_tlb_flush_nonlocked(void)
+{
+
+	stxa(TLB_DEMAP_ALL, ASI_DMMU_DEMAP, 0);
+	stxa(TLB_DEMAP_ALL, ASI_IMMU_DEMAP, 0);
+	flush(KERNBASE);
+}
+
+/*
+ * Flush all user mappings from the TLBs.
+ */
+void
+zeus_tlb_flush_user(void)
+{
+	u_long data, tag;
+	u_int i, slot;
+
+	for (i = 0; i < ZEUS_FTLB_ENTRIES; i++) {
+		slot = TLB_DAR_SLOT(TLB_DAR_FTLB, i);
+		data = ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+		tag = ldxa(slot, ASI_DTLB_TAG_READ_REG);
+		if ((data & TD_V) != 0 && (data & TD_L) == 0 &&
+		    TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+			stxa_sync(slot, ASI_DTLB_DATA_ACCESS_REG, 0);
+		data = ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+		tag = ldxa(slot, ASI_ITLB_TAG_READ_REG);
+		if ((data & TD_V) != 0 && (data & TD_L) == 0 &&
+		    TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+			stxa_sync(slot, ASI_ITLB_DATA_ACCESS_REG, 0);
+	}
+	for (i = 0; i < ZEUS_STLB_ENTRIES; i++) {
+		slot = TLB_DAR_SLOT(TLB_DAR_STLB, i);
+		data = ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+		tag = ldxa(slot, ASI_DTLB_TAG_READ_REG);
+		if ((data & TD_V) != 0 && (data & TD_L) == 0 &&
+		    TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+			stxa_sync(slot, ASI_DTLB_DATA_ACCESS_REG, 0);
+		data = ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+		tag = ldxa(slot, ASI_ITLB_TAG_READ_REG);
+		if ((data & TD_V) != 0 && (data & TD_L) == 0 &&
+		    TLB_TAR_CTX(tag) != TLB_CTX_KERNEL)
+			stxa_sync(slot, ASI_ITLB_DATA_ACCESS_REG, 0);
+	}
+}


Property changes on: trunk/sys/sparc64/sparc64/zeus.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list