summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2001-08-18 19:49:58 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2001-08-18 19:49:58 +0000
commitd348152c6db2646b5de8a40968c60c267c76bc3d (patch)
treea125d1523c9699f519c87976dbb76bef7f3a4b1b /sys/arch
parent7b95461118d83a8f536104debf9493e89f79d1cf (diff)
More includes from NetBSD.
No modifications.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sparc64/include/asm.h157
-rw-r--r--sys/arch/sparc64/include/bus.h1560
-rw-r--r--sys/arch/sparc64/include/ctlreg.h1133
-rw-r--r--sys/arch/sparc64/include/frame.h134
-rw-r--r--sys/arch/sparc64/include/trap.h152
5 files changed, 3136 insertions, 0 deletions
diff --git a/sys/arch/sparc64/include/asm.h b/sys/arch/sparc64/include/asm.h
new file mode 100644
index 00000000000..6ff0de358d5
--- /dev/null
+++ b/sys/arch/sparc64/include/asm.h
@@ -0,0 +1,157 @@
+/* $NetBSD: asm.h,v 1.15 2000/08/02 22:24:39 eeh Exp $ */
+
+/*
+ * Copyright (c) 1994 Allen Briggs
+ * All rights reserved.
+ *
+ * Gleaned from locore.s and sun3 asm.h which had the following copyrights:
+ * locore.s:
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1990 The Regents of the University of California.
+ * sun3/include/asm.h:
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1990 The Regents of the University of California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ASM_H_
+#define _ASM_H_
+
+#ifndef _LOCORE
+#define _LOCORE
+#endif
+#include <machine/frame.h>
+
+#ifdef __arch64__
+#ifndef __ELF__
+#define __ELF__
+#endif
+#endif
+
+/* Pull in CCFSZ, CC64FSZ, and BIAS from frame.h */
+#ifndef _LOCORE
+#define _LOCORE
+#endif
+#include <machine/frame.h>
+
+#ifdef __ELF__
+#define _C_LABEL(name) name
+#else
+#ifdef __STDC__
+#define _C_LABEL(name) _ ## name
+#else
+#define _C_LABEL(name) _/**/name
+#endif
+#endif
+#define _ASM_LABEL(name) name
+
+#ifdef PIC
+/*
+ * PIC_PROLOGUE() is akin to the compiler generated function prologue for
+ * PIC code. It leaves the address of the Global Offset Table in DEST,
+ * clobbering register TMP in the process. Using the temporary enables us
+ * to work without a stack frame (doing so requires saving %o7) .
+ */
+#define PIC_PROLOGUE(dest,tmp) \
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-4),dest; \
+ rd %pc, tmp; \
+ or dest,%lo(_GLOBAL_OFFSET_TABLE_+4),dest; \
+ add dest,tmp,dest
+
+/*
+ * PICCY_SET() does the equivalent of a `set var, %dest' instruction in
+ * a PIC-like way, but without involving the Global Offset Table. This
+ * only works for VARs defined in the same file *and* in the text segment.
+ */
+#define PICCY_SET(var,dest,tmp) \
+ 3: rd %pc, tmp; add tmp,(var-3b),dest
+#else
+#define PIC_PROLOGUE(dest,tmp)
+#define PICCY_OFFSET(var,dest,tmp)
+#endif
+
+#define FTYPE(x) .type x,@function
+#define OTYPE(x) .type x,@object
+
+#define _ENTRY(name) \
+ .align 4; .globl name; .proc 1; FTYPE(name); name:
+
+#ifdef GPROF
+#define _PROF_PROLOGUE \
+ .data; .align 8; 1: .uaword 0; .uaword 0; \
+ .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call _mcount; \
+ or %o0,%lo(1b),%o0; restore
+#else
+#define _PROF_PROLOGUE
+#endif
+
+#define ENTRY(name) _ENTRY(_C_LABEL(name)); _PROF_PROLOGUE
+#define ASENTRY(name) _ENTRY(_ASM_LABEL(name)); _PROF_PROLOGUE
+#define FUNC(name) ASENTRY(name)
+#define RODATA(name) .align 4; .text; .globl _C_LABEL(name); \
+ OTYPE(_C_LABEL(name)); _C_LABEL(name):
+
+
+#define ASMSTR .asciz
+
+#define RCSID(name) .asciz name
+
+#ifdef __ELF__
+#define WEAK_ALIAS(alias,sym) \
+ .weak alias; \
+ alias = sym
+#endif
+
+/*
+ * WARN_REFERENCES: create a warning if the specified symbol is referenced.
+ */
+#ifdef __ELF__
+#ifdef __STDC__
+#define WARN_REFERENCES(_sym,_msg) \
+ .section .gnu.warning. ## _sym ; .ascii _msg ; .text
+#else
+#define WARN_REFERENCES(_sym,_msg) \
+ .section .gnu.warning./**/_sym ; .ascii _msg ; .text
+#endif /* __STDC__ */
+#else
+#ifdef __STDC__
+#define __STRING(x) #x
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg ## ,30,0,0,0 ; \
+ .stabs __STRING(_ ## sym) ## ,1,0,0,0
+#else
+#define __STRING(x) "x"
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg,30,0,0,0 ; \
+ .stabs __STRING(_/**/sym),1,0,0,0
+#endif /* __STDC__ */
+#endif /* __ELF__ */
+
+#endif /* _ASM_H_ */
diff --git a/sys/arch/sparc64/include/bus.h b/sys/arch/sparc64/include/bus.h
new file mode 100644
index 00000000000..104c67c4598
--- /dev/null
+++ b/sys/arch/sparc64/include/bus.h
@@ -0,0 +1,1560 @@
+/* $NetBSD: bus.h,v 1.28 2001/07/19 15:32:19 thorpej Exp $ */
+
+/*-
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef _SPARC_BUS_H_
+#define _SPARC_BUS_H_
+
+#include <machine/types.h>
+#include <machine/ctlreg.h>
+
+/*
+ * Debug hooks
+ */
+
+#define BSDB_ACCESS 0x01
+#define BSDB_MAP 0x02
+extern int bus_space_debug;
+
+/*
+ * UPA and SBUS spaces are non-cached and big endian
+ * (except for RAM and PROM)
+ *
+ * PCI spaces are non-cached and little endian
+ */
+
+enum bus_type {
+ UPA_BUS_SPACE,
+ SBUS_BUS_SPACE,
+ PCI_CONFIG_BUS_SPACE,
+ PCI_IO_BUS_SPACE,
+ PCI_MEMORY_BUS_SPACE,
+ LAST_BUS_SPACE
+};
+extern int bus_type_asi[];
+extern int bus_stream_asi[];
+/* For backwards compatibility */
+#define SPARC_BUS_SPACE UPA_BUS_SPACE
+
+#define __BUS_SPACE_HAS_STREAM_METHODS 1
+
+/*
+ * Bus address and size types
+ */
+typedef u_int64_t bus_space_handle_t;
+typedef enum bus_type bus_type_t;
+typedef u_int64_t bus_addr_t;
+typedef u_int64_t bus_size_t;
+
+/*
+ * Access methods for bus resources and address space.
+ */
+typedef struct sparc_bus_space_tag *bus_space_tag_t;
+
+struct sparc_bus_space_tag {
+ void *cookie;
+ bus_space_tag_t parent;
+ int type;
+
+ int (*sparc_bus_map) __P((
+ bus_space_tag_t,
+ bus_type_t,
+ bus_addr_t,
+ bus_size_t,
+ int, /*flags*/
+ vaddr_t, /*preferred vaddr*/
+ bus_space_handle_t *));
+ int (*sparc_bus_unmap) __P((
+ bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t));
+ int (*sparc_bus_subregion) __P((
+ bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t, /*offset*/
+ bus_size_t, /*size*/
+ bus_space_handle_t *));
+
+ void (*sparc_bus_barrier) __P((
+ bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t, /*offset*/
+ bus_size_t, /*size*/
+ int)); /*flags*/
+
+ int (*sparc_bus_mmap) __P((
+ bus_space_tag_t,
+ bus_type_t, /**/
+ bus_addr_t, /**/
+ int, /*flags*/
+ bus_space_handle_t *));
+
+ void *(*sparc_intr_establish) __P((
+ bus_space_tag_t,
+ int, /*bus-specific intr*/
+ int, /*device class level,
+ see machine/intr.h*/
+ int, /*flags*/
+ int (*) __P((void *)), /*handler*/
+ void *)); /*handler arg*/
+
+};
+
+#if 0
+/*
+ * The following macro could be used to generate the bus_space*() functions
+ * but it uses a gcc extension and is ANSI-only.
+#define PROTO_bus_space_xxx __P((bus_space_tag_t t, ...))
+#define RETURNTYPE_bus_space_xxx void *
+#define BUSFUN(name, returntype, t, args...) \
+ __inline__ RETURNTYPE_##name \
+ bus_##name PROTO_##name \
+ { \
+ while (t->sparc_##name == NULL) \
+ t = t->parent; \
+ return (*(t)->sparc_##name)(t, args); \
+ }
+ */
+#endif
+
+/*
+ * Bus space function prototypes.
+ */
+static int bus_space_map __P((
+ bus_space_tag_t,
+ bus_addr_t,
+ bus_size_t,
+ int, /*flags*/
+ bus_space_handle_t *));
+static int bus_space_map2 __P((
+ bus_space_tag_t,
+ bus_type_t,
+ bus_addr_t,
+ bus_size_t,
+ int, /*flags*/
+ vaddr_t, /*preferred vaddr*/
+ bus_space_handle_t *));
+static int bus_space_unmap __P((
+ bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t));
+static int bus_space_subregion __P((
+ bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_size_t,
+ bus_space_handle_t *));
+static void bus_space_barrier __P((
+ bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_size_t,
+ int));
+static int bus_space_mmap __P((
+ bus_space_tag_t,
+ bus_type_t, /**/
+ bus_addr_t, /**/
+ int, /*flags*/
+ bus_space_handle_t *));
+static void *bus_intr_establish __P((
+ bus_space_tag_t,
+ int, /*bus-specific intr*/
+ int, /*device class level,
+ see machine/intr.h*/
+ int, /*flags*/
+ int (*) __P((void *)), /*handler*/
+ void *)); /*handler arg*/
+
+
+/* This macro finds the first "upstream" implementation of method `f' */
+#define _BS_CALL(t,f) \
+ while (t->f == NULL) \
+ t = t->parent; \
+ return (*(t)->f)
+
+__inline__ int
+bus_space_map(t, a, s, f, hp)
+ bus_space_tag_t t;
+ bus_addr_t a;
+ bus_size_t s;
+ int f;
+ bus_space_handle_t *hp;
+{
+ _BS_CALL(t, sparc_bus_map)((t), 0, (a), (s), (f), 0, (hp));
+}
+
+__inline__ int
+bus_space_map2(t, bt, a, s, f, v, hp)
+ bus_space_tag_t t;
+ bus_type_t bt;
+ bus_addr_t a;
+ bus_size_t s;
+ int f;
+ vaddr_t v;
+ bus_space_handle_t *hp;
+{
+ _BS_CALL(t, sparc_bus_map)(t, bt, a, s, f, v, hp);
+}
+
+__inline__ int
+bus_space_unmap(t, h, s)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t s;
+{
+ _BS_CALL(t, sparc_bus_unmap)(t, h, s);
+}
+
+__inline__ int
+bus_space_subregion(t, h, o, s, hp)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o;
+ bus_size_t s;
+ bus_space_handle_t *hp;
+{
+ _BS_CALL(t, sparc_bus_subregion)(t, h, o, s, hp);
+}
+
+__inline__ int
+bus_space_mmap(t, bt, a, f, hp)
+ bus_space_tag_t t;
+ bus_type_t bt;
+ bus_addr_t a;
+ int f;
+ bus_space_handle_t *hp;
+{
+ _BS_CALL(t, sparc_bus_mmap)(t, bt, a, f, hp);
+}
+
+__inline__ void *
+bus_intr_establish(t, p, l, f, h, a)
+ bus_space_tag_t t;
+ int p;
+ int l;
+ int f;
+ int (*h)__P((void *));
+ void *a;
+{
+ _BS_CALL(t, sparc_intr_establish)(t, p, l, f, h, a);
+}
+
+__inline__ void
+bus_space_barrier(t, h, o, s, f)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o;
+ bus_size_t s;
+ int f;
+{
+ _BS_CALL(t, sparc_bus_barrier)(t, h, o, s, f);
+}
+
+
+#if 0
+int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
+ bus_addr_t rend, bus_size_t size, bus_size_t align,
+ bus_size_t boundary, int flags, bus_addr_t *addrp,
+ bus_space_handle_t *bshp));
+void bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
+ bus_size_t size));
+#endif
+
+/* 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
+#define BUS_SPACE_MAP_BUS1 0x0100 /* placeholders for bus functions... */
+#define BUS_SPACE_MAP_BUS2 0x0200
+#define BUS_SPACE_MAP_BUS3 0x0400
+#define BUS_SPACE_MAP_BUS4 0x0800
+
+
+/* flags for intr_establish() */
+#define BUS_INTR_ESTABLISH_FASTTRAP 1
+#define BUS_INTR_ESTABLISH_SOFTINTR 2
+
+/* flags for bus_space_barrier() */
+#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
+#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
+
+/*
+ * Device space probe assistant.
+ * The optional callback function's arguments are:
+ * the temporary virtual address
+ * the passed `arg' argument
+ */
+int bus_space_probe __P((
+ bus_space_tag_t,
+ bus_type_t,
+ bus_addr_t,
+ bus_size_t, /* probe size */
+ size_t, /* offset */
+ int, /* flags */
+ int (*) __P((void *, void *)), /* callback function */
+ void *)); /* callback arg */
+
+
+/*
+ * u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset));
+ *
+ * Read a 1, 2, 4, or 8 byte quantity from bus space
+ * described by tag/handle/offset.
+ */
+#ifndef BUS_SPACE_DEBUG
+#define bus_space_read_1(t, h, o) \
+ lduba((h) + (o), bus_type_asi[(t)->type])
+
+#define bus_space_read_2(t, h, o) \
+ lduha((h) + (o), bus_type_asi[(t)->type])
+
+#define bus_space_read_4(t, h, o) \
+ lda((h) + (o), bus_type_asi[(t)->type])
+
+#define bus_space_read_8(t, h, o) \
+ ldxa((h) + (o), bus_type_asi[(t)->type])
+#else
+#define bus_space_read_1(t, h, o) ({ \
+ unsigned char __bv = \
+ lduba((h) + (o), bus_type_asi[(t)->type]); \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsr1(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_type_asi[(t)->type], (unsigned int) __bv); \
+ __bv; })
+
+#define bus_space_read_2(t, h, o) ({ \
+ unsigned short __bv = \
+ lduha((h) + (o), bus_type_asi[(t)->type]); \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsr2(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_type_asi[(t)->type], (unsigned int)__bv); \
+ __bv; })
+
+#define bus_space_read_4(t, h, o) ({ \
+ unsigned int __bv = \
+ lda((h) + (o), bus_type_asi[(t)->type]); \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsr4(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_type_asi[(t)->type], __bv); \
+ __bv; })
+
+#define bus_space_read_8(t, h, o) ({ \
+ u_int64_t __bv = \
+ ldxa((h) + (o), bus_type_asi[(t)->type]); \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsr8(%llx + %llx, %x) -> %llx\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_type_asi[(t)->type], __bv); \
+ __bv; })
+#endif
+/*
+ * void bus_space_read_multi_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * u_intN_t *addr, size_t count));
+ *
+ * Read `count' 1, 2, 4, or 8 byte quantities from bus space
+ * described by tag/handle/offset and copy into buffer provided.
+ */
+
+#define bus_space_read_multi_1(t, h, o, a, c) do { \
+ int i = c; \
+ u_int8_t *p = (u_int8_t *)a; \
+ while (i-- > 0) \
+ *p++ = bus_space_read_1(t, h, o); \
+} while (0)
+
+#define bus_space_read_multi_2(t, h, o, a, c) do { \
+ int i = c; \
+ u_int16_t *p = (u_int16_t *)a; \
+ while (i-- > 0) \
+ *p++ = bus_space_read_2(t, h, o); \
+} while (0)
+
+#define bus_space_read_multi_4(t, h, o, a, c) do { \
+ int i = c; \
+ u_int32_t *p = (u_int32_t *)a; \
+ while (i-- > 0) \
+ *p++ = bus_space_read_4(t, h, o); \
+} while (0)
+
+#define bus_space_read_multi_8(t, h, o, a, c) do { \
+ int i = c; \
+ u_int64_t *p = (u_int64_t *)a; \
+ while (i-- > 0) \
+ *p++ = bus_space_read_8(t, h, o); \
+} while (0)
+
+/*
+ * void bus_space_write_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * u_intN_t value));
+ *
+ * Write the 1, 2, 4, or 8 byte value `value' to bus space
+ * described by tag/handle/offset.
+ */
+#ifndef BUS_SPACE_DEBUG
+#define bus_space_write_1(t, h, o, v) \
+ ((void)(stba((h) + (o), bus_type_asi[(t)->type], (v))))
+
+#define bus_space_write_2(t, h, o, v) \
+ ((void)(stha((h) + (o), bus_type_asi[(t)->type], (v))))
+
+#define bus_space_write_4(t, h, o, v) \
+ ((void)(sta((h) + (o), bus_type_asi[(t)->type], (v))))
+
+#define bus_space_write_8(t, h, o, v) \
+ ((void)(stxa((h) + (o), bus_type_asi[(t)->type], (v))))
+#else
+#define bus_space_write_1(t, h, o, v) ({ \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsw1(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_type_asi[(t)->type], (unsigned int) v); \
+ ((void)(stba((h) + (o), bus_type_asi[(t)->type], (v)))); })
+
+#define bus_space_write_2(t, h, o, v) ({ \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsw2(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_type_asi[(t)->type], (unsigned int) v); \
+ ((void)(stha((h) + (o), bus_type_asi[(t)->type], (v)))); })
+
+#define bus_space_write_4(t, h, o, v) ({ \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsw4(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_type_asi[(t)->type], (unsigned int) v); \
+ ((void)(sta((h) + (o), bus_type_asi[(t)->type], (v)))); })
+
+#define bus_space_write_8(t, h, o, v) ({ \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsw8(%llx + %llx, %x) <- %llx\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_type_asi[(t)->type], (u_int64_t) v); \
+ ((void)(stxa((h) + (o), bus_type_asi[(t)->type], (v)))); })
+#endif
+/*
+ * void bus_space_write_multi_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * const u_intN_t *addr, size_t count));
+ *
+ * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
+ * provided to bus space described by tag/handle/offset.
+ */
+
+#define bus_space_write_multi_1(t, h, o, a, c) do { \
+ int i = c; \
+ u_int8_t *p = (u_int8_t *)a; \
+ while (i-- > 0) \
+ bus_space_write_1(t, h, o, *p++); \
+} while (0)
+
+#define bus_space_write_multi_2(t, h, o, a, c) do { \
+ int i = c; \
+ u_int16_t *p = (u_int16_t *)a; \
+ while (i-- > 0) \
+ bus_space_write_2(t, h, o, *p++); \
+} while (0)
+
+#define bus_space_write_multi_4(t, h, o, a, c) do { \
+ int i = c; \
+ u_int32_t *p = (u_int32_t *)a; \
+ while (i-- > 0) \
+ bus_space_write_4(t, h, o, *p++); \
+} while (0)
+
+#define bus_space_write_multi_8(t, h, o, a, c) do { \
+ int i = c; \
+ u_int64_t *p = (u_int64_t *)a; \
+ while (i-- > 0) \
+ bus_space_write_8(t, h, o, *p++); \
+} while (0)
+
+/*
+ * void bus_space_set_multi_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
+ * size_t count));
+ *
+ * Write the 1, 2, 4, or 8 byte value `val' to bus space described
+ * by tag/handle/offset `count' times.
+ */
+
+#define bus_space_set_multi_1(t, h, o, v, c) do { \
+ int i = c; \
+ while (i-- > 0) \
+ bus_space_write_1(t, h, o, v); \
+} while (0)
+
+#define bus_space_set_multi_2(t, h, o, v, c) do { \
+ int i = c; \
+ while (i-- > 0) \
+ bus_space_write_2(t, h, o, v); \
+} while (0)
+
+#define bus_space_set_multi_4(t, h, o, v, c) do { \
+ int i = c; \
+ while (i-- > 0) \
+ bus_space_write_4(t, h, o, v); \
+} while (0)
+
+#define bus_space_set_multi_8(t, h, o, v, c) do { \
+ int i = c; \
+ while (i-- > 0) \
+ bus_space_write_8(t, h, o, v); \
+} while (0)
+
+/*
+ * void bus_space_read_region_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t off,
+ * u_intN_t *addr, bus_size_t count));
+ *
+ */
+static void bus_space_read_region_1 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ u_int8_t *,
+ bus_size_t));
+static void bus_space_read_region_2 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ u_int16_t *,
+ bus_size_t));
+static void bus_space_read_region_4 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ u_int32_t *,
+ bus_size_t));
+static void bus_space_read_region_8 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ u_int64_t *,
+ bus_size_t));
+
+static __inline__ void
+bus_space_read_region_1(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ u_int8_t *a;
+{
+ for (; c; a++, c--, o++)
+ *a = bus_space_read_1(t, h, o);
+}
+static __inline__ void
+bus_space_read_region_2(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ u_int16_t *a;
+{
+ for (; c; a++, c--, o+=2)
+ *a = bus_space_read_2(t, h, o);
+ }
+static __inline__ void
+bus_space_read_region_4(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ u_int32_t *a;
+{
+ for (; c; a++, c--, o+=4)
+ *a = bus_space_read_4(t, h, o);
+}
+static __inline__ void
+bus_space_read_region_8(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ u_int64_t *a;
+{
+ for (; c; a++, c--, o+=8)
+ *a = bus_space_read_8(t, h, o);
+}
+
+/*
+ * void bus_space_write_region_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t off,
+ * u_intN_t *addr, bus_size_t count));
+ *
+ */
+static void bus_space_write_region_1 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int8_t *,
+ bus_size_t));
+static void bus_space_write_region_2 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int16_t *,
+ bus_size_t));
+static void bus_space_write_region_4 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int32_t *,
+ bus_size_t));
+static void bus_space_write_region_8 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int64_t *,
+ bus_size_t));
+static __inline__ void
+bus_space_write_region_1(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int8_t *a;
+{
+ for (; c; a++, c--, o++)
+ bus_space_write_1(t, h, o, *a);
+}
+
+static __inline__ void
+bus_space_write_region_2(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int16_t *a;
+{
+ for (; c; a++, c--, o+=2)
+ bus_space_write_2(t, h, o, *a);
+}
+
+static __inline__ void
+bus_space_write_region_4(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int32_t *a;
+{
+ for (; c; a++, c--, o+=4)
+ bus_space_write_4(t, h, o, *a);
+}
+
+static __inline__ void
+bus_space_write_region_8(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int64_t *a;
+{
+ for (; c; a++, c--, o+=8)
+ bus_space_write_8(t, h, o, *a);
+}
+
+
+/*
+ * void bus_space_set_region_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t off,
+ * u_intN_t *addr, bus_size_t count));
+ *
+ */
+static void bus_space_set_region_1 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int8_t,
+ bus_size_t));
+static void bus_space_set_region_2 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int16_t,
+ bus_size_t));
+static void bus_space_set_region_4 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int32_t,
+ bus_size_t));
+static void bus_space_set_region_8 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int64_t,
+ bus_size_t));
+
+static __inline__ void
+bus_space_set_region_1(t, h, o, v, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int8_t v;
+{
+ for (; c; c--, o++)
+ bus_space_write_1(t, h, o, v);
+}
+
+static __inline__ void
+bus_space_set_region_2(t, h, o, v, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int16_t v;
+{
+ for (; c; c--, o+=2)
+ bus_space_write_2(t, h, o, v);
+}
+
+static __inline__ void
+bus_space_set_region_4(t, h, o, v, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int32_t v;
+{
+ for (; c; c--, o+=4)
+ bus_space_write_4(t, h, o, v);
+}
+
+static __inline__ void
+bus_space_set_region_8(t, h, o, v, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int64_t v;
+{
+ for (; c; c--, o+=8)
+ bus_space_write_8(t, h, o, v);
+}
+
+
+/*
+ * void bus_space_copy_region_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh1, bus_size_t off1,
+ * bus_space_handle_t bsh2, bus_size_t off2,
+ * bus_size_t count));
+ *
+ * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
+ * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
+ */
+static void bus_space_copy_region_1 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_size_t));
+static void bus_space_copy_region_2 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_size_t));
+static void bus_space_copy_region_4 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_size_t));
+static void bus_space_copy_region_8 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_size_t));
+
+
+static __inline__ void
+bus_space_copy_region_1(t, h1, o1, h2, o2, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h1, h2;
+ bus_size_t o1, 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(t, h1, o1, h2, o2, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h1, h2;
+ bus_size_t o1, 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(t, h1, o1, h2, o2, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h1, h2;
+ bus_size_t o1, 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(t, h1, o1, h2, o2, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h1, h2;
+ bus_size_t o1, 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));
+}
+
+/*
+ * u_intN_t bus_space_read_stream_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset));
+ *
+ * Read a 1, 2, 4, or 8 byte quantity from bus space
+ * described by tag/handle/offset.
+ */
+#ifndef BUS_SPACE_DEBUG
+#define bus_space_read_stream_1(t, h, o) \
+ lduba((h) + (o), bus_stream_asi[(t)->type])
+
+#define bus_space_read_stream_2(t, h, o) \
+ lduha((h) + (o), bus_stream_asi[(t)->type])
+
+#define bus_space_read_stream_4(t, h, o) \
+ lda((h) + (o), bus_stream_asi[(t)->type])
+
+#define bus_space_read_stream_8(t, h, o) \
+ ldxa((h) + (o), bus_stream_asi[(t)->type])
+#else
+#define bus_space_read_stream_1(t, h, o) ({ \
+ unsigned char __bv = \
+ lduba((h) + (o), bus_stream_asi[(t)->type]); \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsr1(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_stream_asi[(t)->type], (unsigned int) __bv); \
+ __bv; })
+
+#define bus_space_read_stream_2(t, h, o) ({ \
+ unsigned short __bv = \
+ lduha((h) + (o), bus_stream_asi[(t)->type]); \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsr2(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_stream_asi[(t)->type], (unsigned int)__bv); \
+ __bv; })
+
+#define bus_space_read_stream_4(t, h, o) ({ \
+ unsigned int __bv = \
+ lda((h) + (o), bus_stream_asi[(t)->type]); \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsr4(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_stream_asi[(t)->type], __bv); \
+ __bv; })
+
+#define bus_space_read_stream_8(t, h, o) ({ \
+ u_int64_t __bv = \
+ ldxa((h) + (o), bus_stream_asi[(t)->type]); \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsr8(%llx + %llx, %x) -> %llx\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_stream_asi[(t)->type], __bv); \
+ __bv; })
+#endif
+/*
+ * void bus_space_read_multi_stream_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * u_intN_t *addr, size_t count));
+ *
+ * Read `count' 1, 2, 4, or 8 byte quantities from bus space
+ * described by tag/handle/offset and copy into buffer provided.
+ */
+
+#define bus_space_read_multi_stream_1(t, h, o, a, c) do { \
+ int i = c; \
+ u_int8_t *p = (u_int8_t *)a; \
+ while (i-- > 0) \
+ *p++ = bus_space_read_stream_1(t, h, o); \
+} while (0)
+
+#define bus_space_read_multi_stream_2(t, h, o, a, c) do { \
+ int i = c; \
+ u_int16_t *p = (u_int16_t *)a; \
+ while (i-- > 0) \
+ *p++ = bus_space_read_stream_2(t, h, o); \
+} while (0)
+
+#define bus_space_read_multi_stream_4(t, h, o, a, c) do { \
+ int i = c; \
+ u_int32_t *p = (u_int32_t *)a; \
+ while (i-- > 0) \
+ *p++ = bus_space_read_stream_4(t, h, o); \
+} while (0)
+
+#define bus_space_read_multi_stream_8(t, h, o, a, c) do { \
+ int i = c; \
+ u_int64_t *p = (u_int64_t *)a; \
+ while (i-- > 0) \
+ *p++ = bus_space_read_stream_8(t, h, o); \
+} while (0)
+
+/*
+ * void bus_space_write_stream_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * u_intN_t value));
+ *
+ * Write the 1, 2, 4, or 8 byte value `value' to bus space
+ * described by tag/handle/offset.
+ */
+#ifndef BUS_SPACE_DEBUG
+#define bus_space_write_stream_1(t, h, o, v) \
+ ((void)(stba((h) + (o), bus_stream_asi[(t)->type], (v))))
+
+#define bus_space_write_stream_2(t, h, o, v) \
+ ((void)(stha((h) + (o), bus_stream_asi[(t)->type], (v))))
+
+#define bus_space_write_stream_4(t, h, o, v) \
+ ((void)(sta((h) + (o), bus_stream_asi[(t)->type], (v))))
+
+#define bus_space_write_stream_8(t, h, o, v) \
+ ((void)(stxa((h) + (o), bus_stream_asi[(t)->type], (v))))
+#else
+#define bus_space_write_stream_1(t, h, o, v) ({ \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsw1(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_stream_asi[(t)->type], (unsigned int) v); \
+ ((void)(stba((h) + (o), bus_stream_asi[(t)->type], (v)))); })
+
+#define bus_space_write_stream_2(t, h, o, v) ({ \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsw2(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_stream_asi[(t)->type], (unsigned int) v); \
+ ((void)(stha((h) + (o), bus_stream_asi[(t)->type], (v)))); })
+
+#define bus_space_write_stream_4(t, h, o, v) ({ \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsw4(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_stream_asi[(t)->type], (unsigned int) v); \
+ ((void)(sta((h) + (o), bus_stream_asi[(t)->type], (v)))); })
+
+#define bus_space_write_stream_8(t, h, o, v) ({ \
+ if (bus_space_debug & BSDB_ACCESS) \
+ printf("bsw8(%llx + %llx, %x) <- %llx\n", (u_int64_t)(h), \
+ (u_int64_t)(o), \
+ bus_stream_asi[(t)->type], (u_int64_t) v); \
+ ((void)(stxa((h) + (o), bus_stream_asi[(t)->type], (v)))); })
+#endif
+/*
+ * void bus_space_write_multi_stream_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * const u_intN_t *addr, size_t count));
+ *
+ * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
+ * provided to bus space described by tag/handle/offset.
+ */
+
+#define bus_space_write_multi_stream_1(t, h, o, a, c) do { \
+ int i = c; \
+ u_int8_t *p = (u_int8_t *)a; \
+ while (i-- > 0) \
+ bus_space_write_stream_1(t, h, o, *p++); \
+} while (0)
+
+#define bus_space_write_multi_stream_2(t, h, o, a, c) do { \
+ int i = c; \
+ u_int16_t *p = (u_int16_t *)a; \
+ while (i-- > 0) \
+ bus_space_write_stream_2(t, h, o, *p++); \
+} while (0)
+
+#define bus_space_write_multi_stream_4(t, h, o, a, c) do { \
+ int i = c; \
+ u_int32_t *p = (u_int32_t *)a; \
+ while (i-- > 0) \
+ bus_space_write_stream_4(t, h, o, *p++); \
+} while (0)
+
+#define bus_space_write_multi_stream_8(t, h, o, a, c) do { \
+ int i = c; \
+ u_int64_t *p = (u_int64_t *)a; \
+ while (i-- > 0) \
+ bus_space_write_stream_8(t, h, o, *p++); \
+} while (0)
+
+/*
+ * void bus_space_set_multi_stream_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
+ * size_t count));
+ *
+ * Write the 1, 2, 4, or 8 byte value `val' to bus space described
+ * by tag/handle/offset `count' times.
+ */
+
+#define bus_space_set_multi_stream_1(t, h, o, v, c) do { \
+ int i = c; \
+ while (i-- > 0) \
+ bus_space_write_stream_1(t, h, o, v); \
+} while (0)
+
+#define bus_space_set_multi_stream_2(t, h, o, v, c) do { \
+ int i = c; \
+ while (i-- > 0) \
+ bus_space_write_stream_2(t, h, o, v); \
+} while (0)
+
+#define bus_space_set_multi_stream_4(t, h, o, v, c) do { \
+ int i = c; \
+ while (i-- > 0) \
+ bus_space_write_stream_4(t, h, o, v); \
+} while (0)
+
+#define bus_space_set_multi_stream_8(t, h, o, v, c) do { \
+ int i = c; \
+ while (i-- > 0) \
+ bus_space_write_stream_8(t, h, o, v); \
+} while (0)
+
+/*
+ * void bus_space_read_region_stream_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t off,
+ * u_intN_t *addr, bus_size_t count));
+ *
+ */
+static void bus_space_read_region_stream_1 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ u_int8_t *,
+ bus_size_t));
+static void bus_space_read_region_stream_2 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ u_int16_t *,
+ bus_size_t));
+static void bus_space_read_region_stream_4 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ u_int32_t *,
+ bus_size_t));
+static void bus_space_read_region_stream_8 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ u_int64_t *,
+ bus_size_t));
+
+static __inline__ void
+bus_space_read_region_stream_1(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ u_int8_t *a;
+{
+ for (; c; a++, c--, o++)
+ *a = bus_space_read_stream_1(t, h, o);
+}
+static __inline__ void
+bus_space_read_region_stream_2(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ u_int16_t *a;
+{
+ for (; c; a++, c--, o+=2)
+ *a = bus_space_read_stream_2(t, h, o);
+ }
+static __inline__ void
+bus_space_read_region_stream_4(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ u_int32_t *a;
+{
+ for (; c; a++, c--, o+=4)
+ *a = bus_space_read_stream_4(t, h, o);
+}
+static __inline__ void
+bus_space_read_region_stream_8(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ u_int64_t *a;
+{
+ for (; c; a++, c--, o+=8)
+ *a = bus_space_read_stream_8(t, h, o);
+}
+
+/*
+ * void bus_space_write_region_stream_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t off,
+ * u_intN_t *addr, bus_size_t count));
+ *
+ */
+static void bus_space_write_region_stream_1 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int8_t *,
+ bus_size_t));
+static void bus_space_write_region_stream_2 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int16_t *,
+ bus_size_t));
+static void bus_space_write_region_stream_4 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int32_t *,
+ bus_size_t));
+static void bus_space_write_region_stream_8 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int64_t *,
+ bus_size_t));
+static __inline__ void
+bus_space_write_region_stream_1(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int8_t *a;
+{
+ for (; c; a++, c--, o++)
+ bus_space_write_stream_1(t, h, o, *a);
+}
+
+static __inline__ void
+bus_space_write_region_stream_2(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int16_t *a;
+{
+ for (; c; a++, c--, o+=2)
+ bus_space_write_stream_2(t, h, o, *a);
+}
+
+static __inline__ void
+bus_space_write_region_stream_4(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int32_t *a;
+{
+ for (; c; a++, c--, o+=4)
+ bus_space_write_stream_4(t, h, o, *a);
+}
+
+static __inline__ void
+bus_space_write_region_stream_8(t, h, o, a, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int64_t *a;
+{
+ for (; c; a++, c--, o+=8)
+ bus_space_write_stream_8(t, h, o, *a);
+}
+
+
+/*
+ * void bus_space_set_region_stream_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t off,
+ * u_intN_t *addr, bus_size_t count));
+ *
+ */
+static void bus_space_set_region_stream_1 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int8_t,
+ bus_size_t));
+static void bus_space_set_region_stream_2 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int16_t,
+ bus_size_t));
+static void bus_space_set_region_stream_4 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int32_t,
+ bus_size_t));
+static void bus_space_set_region_stream_8 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ const u_int64_t,
+ bus_size_t));
+
+static __inline__ void
+bus_space_set_region_stream_1(t, h, o, v, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int8_t v;
+{
+ for (; c; c--, o++)
+ bus_space_write_stream_1(t, h, o, v);
+}
+
+static __inline__ void
+bus_space_set_region_stream_2(t, h, o, v, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int16_t v;
+{
+ for (; c; c--, o+=2)
+ bus_space_write_stream_2(t, h, o, v);
+}
+
+static __inline__ void
+bus_space_set_region_stream_4(t, h, o, v, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int32_t v;
+{
+ for (; c; c--, o+=4)
+ bus_space_write_stream_4(t, h, o, v);
+}
+
+static __inline__ void
+bus_space_set_region_stream_8(t, h, o, v, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ bus_size_t o, c;
+ const u_int64_t v;
+{
+ for (; c; c--, o+=8)
+ bus_space_write_stream_8(t, h, o, v);
+}
+
+
+/*
+ * void bus_space_copy_region_stream_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh1, bus_size_t off1,
+ * bus_space_handle_t bsh2, bus_size_t off2,
+ * bus_size_t count));
+ *
+ * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
+ * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
+ */
+static void bus_space_copy_region_stream_1 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_size_t));
+static void bus_space_copy_region_stream_2 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_size_t));
+static void bus_space_copy_region_stream_4 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_size_t));
+static void bus_space_copy_region_stream_8 __P((bus_space_tag_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_space_handle_t,
+ bus_size_t,
+ bus_size_t));
+
+
+static __inline__ void
+bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h1, h2;
+ bus_size_t o1, 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(t, h1, o1, h2, o2, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h1, h2;
+ bus_size_t o1, 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(t, h1, o1, h2, o2, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h1, h2;
+ bus_size_t o1, 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(t, h1, o1, h2, o2, c)
+ bus_space_tag_t t;
+ bus_space_handle_t h1, h2;
+ bus_size_t o1, 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));
+}
+
+
+#define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
+
+/*
+ * Flags used in various bus DMA methods.
+ */
+#define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */
+#define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */
+#define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */
+#define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */
+#define BUS_DMA_NOWRITE 0x008 /* I suppose the following two should default on */
+#define BUS_DMA_BUS1 0x010
+#define BUS_DMA_BUS2 0x020
+#define BUS_DMA_BUS3 0x040
+#define BUS_DMA_BUS4 0x080
+#define BUS_DMA_STREAMING 0x100 /* hint: sequential, unidirectional */
+#define BUS_DMA_READ 0x200 /* mapping is device -> memory only */
+#define BUS_DMA_WRITE 0x400 /* mapping is memory -> device only */
+
+
+#define BUS_DMA_NOCACHE BUS_DMA_BUS1
+#define BUS_DMA_DVMA BUS_DMA_BUS2 /* Don't bother with alignment */
+
+/* Forwards needed by prototypes below. */
+struct mbuf;
+struct uio;
+
+/*
+ * Operations performed by bus_dmamap_sync().
+ */
+#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
+#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
+#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
+#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
+
+typedef struct sparc_bus_dma_tag *bus_dma_tag_t;
+typedef struct sparc_bus_dmamap *bus_dmamap_t;
+
+/*
+ * bus_dma_segment_t
+ *
+ * Describes a single contiguous DMA transaction. Values
+ * are suitable for programming into DMA registers.
+ */
+struct sparc_bus_dma_segment {
+ bus_addr_t ds_addr; /* DVMA address */
+ bus_size_t ds_len; /* length of transfer */
+ bus_size_t _ds_boundary; /* don't cross this */
+ bus_size_t _ds_align; /* align to this */
+ void *_ds_mlist; /* XXX - dmamap_alloc'ed pages */
+};
+typedef struct sparc_bus_dma_segment bus_dma_segment_t;
+
+
+/*
+ * bus_dma_tag_t
+ *
+ * A machine-dependent opaque type describing the implementation of
+ * DMA for a given bus.
+ */
+struct sparc_bus_dma_tag {
+ void *_cookie; /* cookie used in the guts */
+ struct sparc_bus_dma_tag* _parent;
+
+ /*
+ * DMA mapping methods.
+ */
+ int (*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
+ bus_size_t, bus_size_t, int, bus_dmamap_t *));
+ void (*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
+ int (*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
+ bus_size_t, struct proc *, int));
+ int (*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
+ struct mbuf *, int));
+ int (*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
+ struct uio *, int));
+ int (*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
+ bus_dma_segment_t *, int, bus_size_t, int));
+ void (*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
+ void (*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
+ bus_addr_t, bus_size_t, int));
+
+ /*
+ * DMA memory utility functions.
+ */
+ int (*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
+ bus_size_t, bus_dma_segment_t *, int, int *, int));
+ void (*_dmamem_free) __P((bus_dma_tag_t,
+ bus_dma_segment_t *, int));
+ int (*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
+ int, size_t, caddr_t *, int));
+ void (*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
+ paddr_t (*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
+ int, off_t, int, int));
+};
+
+#define bus_dmamap_create(t, s, n, m, b, f, p) \
+ (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
+#define bus_dmamap_destroy(t, p) \
+ (*(t)->_dmamap_destroy)((t), (p))
+#define bus_dmamap_load(t, m, b, s, p, f) \
+ (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
+#define bus_dmamap_load_mbuf(t, m, b, f) \
+ (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
+#define bus_dmamap_load_uio(t, m, u, f) \
+ (*(t)->_dmamap_load_uio)((t), (m), (u), (f))
+#define bus_dmamap_load_raw(t, m, sg, n, s, f) \
+ (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
+#define bus_dmamap_unload(t, p) \
+ (*(t)->_dmamap_unload)((t), (p))
+#define bus_dmamap_sync(t, p, o, l, ops) \
+ (void)((t)->_dmamap_sync ? \
+ (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
+
+#define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
+ (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
+#define bus_dmamem_free(t, sg, n) \
+ (*(t)->_dmamem_free)((t), (sg), (n))
+#define bus_dmamem_map(t, sg, n, s, k, f) \
+ (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
+#define bus_dmamem_unmap(t, k, s) \
+ (*(t)->_dmamem_unmap)((t), (k), (s))
+#define bus_dmamem_mmap(t, sg, n, o, p, f) \
+ (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
+
+/*
+ * bus_dmamap_t
+ *
+ * Describes a DMA mapping.
+ */
+struct sparc_bus_dmamap {
+ /*
+ * PRIVATE MEMBERS: not for use my machine-independent code.
+ */
+ bus_size_t _dm_size; /* largest DMA transfer mappable */
+ bus_size_t _dm_maxsegsz; /* largest possible segment */
+ bus_size_t _dm_boundary; /* don't cross this */
+ int _dm_segcnt; /* number of segs this map can map */
+ int _dm_flags; /* misc. flags */
+#define _DM_TYPE_LOAD 0
+#define _DM_TYPE_SEGS 1
+#define _DM_TYPE_UIO 2
+#define _DM_TYPE_MBUF 3
+ int _dm_type; /* type of mapping: raw, uio, mbuf, etc */
+ void *_dm_source; /* source mbuf, uio, etc. needed for unload *///////////////////////
+
+ void *_dm_cookie; /* cookie for bus-specific functions */
+
+ /*
+ * PUBLIC MEMBERS: these are used by machine-independent code.
+ */
+ bus_size_t dm_mapsize; /* size of the mapping */
+ int dm_nsegs; /* # valid segments in mapping */
+ bus_dma_segment_t dm_segs[1]; /* segments; variable length */
+};
+
+#ifdef _SPARC_BUS_DMA_PRIVATE
+int _bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
+ bus_size_t, int, bus_dmamap_t *));
+void _bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
+int _bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
+ bus_size_t, struct proc *, int));
+int _bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
+ struct mbuf *, int));
+int _bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
+ struct uio *, int));
+int _bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
+ bus_dma_segment_t *, int, bus_size_t, int));
+void _bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
+void _bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
+ bus_size_t, int));
+
+int _bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
+ bus_size_t alignment, bus_size_t boundary,
+ bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
+void _bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
+ int nsegs));
+int _bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
+ int nsegs, size_t size, caddr_t *kvap, int flags));
+void _bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
+ size_t size));
+paddr_t _bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
+ int nsegs, off_t off, int prot, int flags));
+
+int _bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
+ bus_size_t alignment, bus_size_t boundary,
+ bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
+ vaddr_t low, vaddr_t high));
+#endif /* _SPARC_BUS_DMA_PRIVATE */
+
+#endif /* _SPARC_BUS_H_ */
diff --git a/sys/arch/sparc64/include/ctlreg.h b/sys/arch/sparc64/include/ctlreg.h
new file mode 100644
index 00000000000..d9368450c8e
--- /dev/null
+++ b/sys/arch/sparc64/include/ctlreg.h
@@ -0,0 +1,1133 @@
+/* $NetBSD: ctlreg.h,v 1.28 2001/08/06 23:55:34 eeh Exp $ */
+
+/*
+ * Copyright (c) 1996-2001 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.
+ *
+ */
+
+/*
+ * Sun 4u control registers. (includes address space definitions
+ * and some registers in control space).
+ */
+
+/*
+ * The Alternate address spaces.
+ *
+ * 0x00-0x7f are privileged
+ * 0x80-0xff can be used by users
+ */
+
+#define ASI_LITTLE 0x08 /* This bit should make an ASI little endian */
+
+#define ASI_NUCLEUS 0x04 /* [4u] kernel address space */
+#define ASI_NUCLEUS_LITTLE 0x0c /* [4u] kernel address space, little endian */
+
+#define ASI_AS_IF_USER_PRIMARY 0x10 /* [4u] primary user address space */
+#define ASI_AS_IF_USER_SECONDARY 0x11 /* [4u] secondary user address space */
+
+#define ASI_PHYS_CACHED 0x14 /* [4u] MMU bypass to main memory */
+#define ASI_PHYS_NON_CACHED 0x15 /* [4u] MMU bypass to I/O location */
+
+#define ASI_AS_IF_USER_PRIMARY_LITTLE 0x18 /* [4u] primary user address space, little endian */
+#define ASI_AS_IF_USER_SECONDARY_LITTIE 0x19 /* [4u] secondary user address space, little endian */
+
+#define ASI_PHYS_CACHED_LITTLE 0x1c /* [4u] MMU bypass to main memory, little endian */
+#define ASI_PHYS_NON_CACHED_LITTLE 0x1d /* [4u] MMU bypass to I/O location, little endian */
+
+#define ASI_NUCLEUS_QUAD_LDD 0x24 /* [4u] use w/LDDA to load 128-bit item */
+#define ASI_NUCLEUS_QUAD_LDD_LITTLE 0x2c /* [4u] use w/LDDA to load 128-bit item, little endian */
+
+#define ASI_FLUSH_D_PAGE_PRIMARY 0x38 /* [4u] flush D-cache page using primary context */
+#define ASI_FLUSH_D_PAGE_SECONDARY 0x39 /* [4u] flush D-cache page using secondary context */
+#define ASI_FLUSH_D_CTX_PRIMARY 0x3a /* [4u] flush D-cache context using primary context */
+#define ASI_FLUSH_D_CTX_SECONDARY 0x3b /* [4u] flush D-cache context using secondary context */
+
+#define ASI_LSU_CONTROL_REGISTER 0x45 /* [4u] load/store unit control register */
+
+#define ASI_DCACHE_DATA 0x46 /* [4u] diagnostic access to D-cache data RAM */
+#define ASI_DCACHE_TAG 0x47 /* [4u] diagnostic access to D-cache tag RAM */
+
+#define ASI_INTR_DISPATCH_STATUS 0x48 /* [4u] interrupt dispatch status register */
+#define ASI_INTR_RECEIVE 0x49 /* [4u] interrupt receive status register */
+#define ASI_MID_REG 0x4a /* [4u] hardware config and MID */
+#define ASI_ERROR_EN_REG 0x4b /* [4u] asynchronous error enables */
+#define ASI_AFSR 0x4c /* [4u] asynchronous fault status register */
+#define ASI_AFAR 0x4d /* [4u] asynchronous fault address register */
+
+#define ASI_ICACHE_DATA 0x66 /* [4u] diagnostic access to D-cache data RAM */
+#define ASI_ICACHE_TAG 0x67 /* [4u] diagnostic access to D-cache tag RAM */
+#define ASI_FLUSH_I_PAGE_PRIMARY 0x68 /* [4u] flush D-cache page using primary context */
+#define ASI_FLUSH_I_PAGE_SECONDARY 0x69 /* [4u] flush D-cache page using secondary context */
+#define ASI_FLUSH_I_CTX_PRIMARY 0x6a /* [4u] flush D-cache context using primary context */
+#define ASI_FLUSH_I_CTX_SECONDARY 0x6b /* [4u] flush D-cache context using secondary context */
+
+#define ASI_BLOCK_AS_IF_USER_PRIMARY 0x70 /* [4u] primary user address space, block loads/stores */
+#define ASI_BLOCK_AS_IF_USER_SECONDARY 0x71 /* [4u] secondary user address space, block loads/stores */
+
+#define ASI_ECACHE_DIAG 0x76 /* [4u] diag access to E-cache tag and data */
+#define ASI_DATAPATH_ERR_REG_WRITE 0x77 /* [4u] ASI is reused */
+
+#define ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE 0x78 /* [4u] primary user address space, block loads/stores */
+#define ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE 0x79 /* [4u] secondary user address space, block loads/stores */
+
+#define ASI_INTERRUPT_RECEIVE_DATA 0x7f /* [4u] interrupt receive data registers {0,1,2} */
+#define ASI_DATAPATH_ERR_REG_READ 0x7f /* [4u] read access to datapath error registers (ASI reused) */
+
+#define ASI_PRIMARY 0x80 /* [4u] primary address space */
+#define ASI_SECONDARY 0x81 /* [4u] secondary address space */
+#define ASI_PRIMARY_NOFAULT 0x82 /* [4u] primary address space, no fault */
+#define ASI_SECONDARY_NOFAULT 0x83 /* [4u] secondary address space, no fault */
+
+#define ASI_PRIMARY_LITTLE 0x88 /* [4u] primary address space, little endian */
+#define ASI_SECONDARY_LITTLE 0x89 /* [4u] secondary address space, little endian */
+#define ASI_PRIMARY_NOFAULT_LITTLE 0x8a /* [4u] primary address space, no fault, little endian */
+#define ASI_SECONDARY_NOFAULT_LITTLE 0x8b /* [4u] secondary address space, no fault, little endian */
+
+#define ASI_PST8_PRIMARY 0xc0 /* [VIS] Eight 8-bit partial store, primary */
+#define ASI_PST8_SECONDARY 0xc1 /* [VIS] Eight 8-bit partial store, secondary */
+#define ASI_PST16_PRIMARY 0xc2 /* [VIS] Four 16-bit partial store, primary */
+#define ASI_PST16_SECONDARY 0xc3 /* [VIS] Fout 16-bit partial store, secondary */
+#define ASI_PST32_PRIMARY 0xc4 /* [VIS] Two 32-bit partial store, primary */
+#define ASI_PST32_SECONDARY 0xc5 /* [VIS] Two 32-bit partial store, secondary */
+
+#define ASI_PST8_PRIMARY_LITTLE 0xc8 /* [VIS] Eight 8-bit partial store, primary, little endian */
+#define ASI_PST8_SECONDARY_LITTLE 0xc9 /* [VIS] Eight 8-bit partial store, secondary, little endian */
+#define ASI_PST16_PRIMARY_LITTLE 0xca /* [VIS] Four 16-bit partial store, primary, little endian */
+#define ASI_PST16_SECONDARY_LITTLE 0xcb /* [VIS] Fout 16-bit partial store, secondary, little endian */
+#define ASI_PST32_PRIMARY_LITTLE 0xcc /* [VIS] Two 32-bit partial store, primary, little endian */
+#define ASI_PST32_SECONDARY_LITTLE 0xcd /* [VIS] Two 32-bit partial store, secondary, little endian */
+
+#define ASI_FL8_PRIMARY 0xd0 /* [VIS] One 8-bit load/store floating, primary */
+#define ASI_FL8_SECONDARY 0xd1 /* [VIS] One 8-bit load/store floating, secondary */
+#define ASI_FL16_PRIMARY 0xd2 /* [VIS] One 16-bit load/store floating, primary */
+#define ASI_FL16_SECONDARY 0xd3 /* [VIS] One 16-bit load/store floating, secondary */
+
+#define ASI_FL8_PRIMARY_LITTLE 0xd8 /* [VIS] One 8-bit load/store floating, primary, little endian */
+#define ASI_FL8_SECONDARY_LITTLE 0xd9 /* [VIS] One 8-bit load/store floating, secondary, little endian */
+#define ASI_FL16_PRIMARY_LITTLE 0xda /* [VIS] One 16-bit load/store floating, primary, little endian */
+#define ASI_FL16_SECONDARY_LITTLE 0xdb /* [VIS] One 16-bit load/store floating, secondary, little endian */
+
+#define ASI_BLOCK_COMMIT_PRIMARY 0xe0 /* [4u] block store with commit, primary */
+#define ASI_BLOCK_COMMIT_SECONDARY 0xe1 /* [4u] block store with commit, secondary */
+#define ASI_BLOCK_PRIMARY 0xf0 /* [4u] block load/store, primary */
+#define ASI_BLOCK_SECONDARY 0xf1 /* [4u] block load/store, secondary */
+#define ASI_BLOCK_PRIMARY_LITTLE 0xf8 /* [4u] block load/store, primary, little endian */
+#define ASI_BLOCK_SECONDARY_LITTLE 0xf9 /* [4u] block load/store, secondary, little endian */
+
+
+/*
+ * These are the shorter names used by Solaris
+ */
+
+#define ASI_N ASI_NUCLEUS
+#define ASI_NL ASI_NUCLEUS_LITTLE
+#define ASI_AIUP ASI_AS_IF_USER_PRIMARY
+#define ASI_AIUS ASI_AS_IF_USER_SECONDARY
+#define ASI_AIUPL ASI_AS_IF_USER_PRIMARY_LITTLE
+#define ASI_AIUSL ASI_AS_IF_USER_SECONDARY_LITTLE
+#define ASI_P ASI_PRIMARY
+#define ASI_S ASI_SECONDARY
+#define ASI_PNF ASI_PRIMARY_NOFAULT
+#define ASI_SNF ASI_SECONDARY_NOFAULT
+#define ASI_PL ASI_PRIMARY_LITTLE
+#define ASI_SL ASI_SECONDARY_LITTLE
+#define ASI_PNFL ASI_PRIMARY_NOFAULT_LITTLE
+#define ASI_SNFL ASI_SECONDARY_NOFAULT_LITTLE
+#define ASI_FL8_P ASI_FL8_PRIMARY
+#define ASI_FL8_S ASI_FL8_SECONDARY
+#define ASI_FL16_P ASI_FL16_PRIMARY
+#define ASI_FL16_S ASI_FL16_SECONDARY
+#define ASI_FL8_PL ASI_FL8_PRIMARY_LITTLE
+#define ASI_FL8_SL ASI_FL8_SECONDARY_LITTLE
+#define ASI_FL16_PL ASI_FL16_PRIMARY_LITTLE
+#define ASI_FL16_SL ASI_FL16_SECONDARY_LITTLE
+#define ASI_BLK_AIUP ASI_BLOCK_AS_IF_USER_PRIMARY
+#define ASI_BLK_AIUPL ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE
+#define ASI_BLK_AIUS ASI_BLOCK_AS_IF_USER_SECONDARY
+#define ASI_BLK_AIUSL ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE
+#define ASI_BLK_COMMIT_P ASI_BLOCK_COMMIT_PRIMARY
+#define ASI_BLK_COMMIT_PRIMARY ASI_BLOCK_COMMIT_PRIMARY
+#define ASI_BLK_COMMIT_S ASI_BLOCK_COMMIT_SECONDARY
+#define ASI_BLK_COMMIT_SECONDARY ASI_BLOCK_COMMIT_SECONDARY
+#define ASI_BLK_P ASI_BLOCK_PRIMARY
+#define ASI_BLK_PL ASI_BLOCK_PRIMARY_LITTLE
+#define ASI_BLK_S ASI_BLOCK_SECONDARY
+#define ASI_BLK_SL ASI_BLOCK_SECONDARY_LITTLE
+
+/* Alternative spellings */
+#define ASI_PRIMARY_NO_FAULT ASI_PRIMARY_NOFAULT
+#define ASI_PRIMARY_NO_FAULT_LITTLE ASI_PRIMARY_NOFAULT_LITTLE
+#define ASI_SECONDARY_NO_FAULT ASI_SECONDARY_NOFAULT
+#define ASI_SECONDARY_NO_FAULT_LITTLE ASI_SECONDARY_NOFAULT_LITTLE
+
+#define PHYS_ASI(x) (((x) | 0x08) == 0x1c)
+#define LITTLE_ASI(x) ((x) & ASI_LITTLE)
+
+/*
+ * The following are 4u control registers
+ */
+
+
+/* Get the CPU's UPAID */
+#define UPA_CR_MID(x) (((x)>>17)&0x1f)
+#define CPU_UPAID UPA_CR_MID(ldxa(0, ASI_MID_REG))
+
+/*
+ * [4u] MMU and Cache Control Register (MCCR)
+ * use ASI = 0x45
+ */
+#define ASI_MCCR ASI_LSU_CONTROL_REGISTER
+#define MCCR 0x00
+
+/* MCCR Bits and their meanings */
+#define MCCR_DMMU_EN 0x08
+#define MCCR_IMMU_EN 0x04
+#define MCCR_DCACHE_EN 0x02
+#define MCCR_ICACHE_EN 0x01
+
+
+/*
+ * MMU control registers
+ */
+
+/* Choose an MMU */
+#define ASI_DMMU 0x58
+#define ASI_IMMU 0x50
+
+/* Other assorted MMU ASIs */
+#define ASI_IMMU_8KPTR 0x51
+#define ASI_IMMU_64KPTR 0x52
+#define ASI_IMMU_DATA_IN 0x54
+#define ASI_IMMU_TLB_DATA 0x55
+#define ASI_IMMU_TLB_TAG 0x56
+#define ASI_DMMU_8KPTR 0x59
+#define ASI_DMMU_64KPTR 0x5a
+#define ASI_DMMU_DATA_IN 0x5c
+#define ASI_DMMU_TLB_DATA 0x5d
+#define ASI_DMMU_TLB_TAG 0x5e
+
+/*
+ * The following are the control registers
+ * They work on both MMUs unless noted.
+ *
+ * Register contents are defined later on individual registers.
+ */
+#define TSB_TAG_TARGET 0x0
+#define TLB_DATA_IN 0x0
+#define CTX_PRIMARY 0x08 /* primary context -- DMMU only */
+#define CTX_SECONDARY 0x10 /* secondary context -- DMMU only */
+#define SFSR 0x18
+#define SFAR 0x20 /* fault address -- DMMU only */
+#define TSB 0x28
+#define TLB_TAG_ACCESS 0x30
+#define VIRTUAL_WATCHPOINT 0x38
+#define PHYSICAL_WATCHPOINT 0x40
+
+/* Tag Target bits */
+#define TAG_TARGET_VA_MASK 0x03ffffffffffffffffLL
+#define TAG_TARGET_VA(x) (((x)<<22)&TAG_TARGET_VA_MASK)
+#define TAG_TARGET_CONTEXT(x) ((x)>>48)
+#define TAG_TARGET(c,v) ((((uint64_t)c)<<48)|(((uint64_t)v)&TAG_TARGET_VA_MASK))
+
+/* SFSR bits for both D_SFSR and I_SFSR */
+#define SFSR_ASI(x) ((x)>>16)
+#define SFSR_FT_VA_OOR_2 0x02000 /* IMMU: jumpl or return to unsupportd VA */
+#define SFSR_FT_VA_OOR_1 0x01000 /* fault at unsupported VA */
+#define SFSR_FT_NFO 0x00800 /* DMMU: Access to page marked NFO */
+#define SFSR_ILL_ASI 0x00400 /* DMMU: Illegal (unsupported) ASI */
+#define SFSR_FT_IO_ATOMIC 0x00200 /* DMMU: Atomic access to noncacheable page */
+#define SFSR_FT_ILL_NF 0x00100 /* DMMU: NF load or flush to page marked E (has side effects) */
+#define SFSR_FT_PRIV 0x00080 /* Privilege violation */
+#define SFSR_FT_E 0x00040 /* DMUU: value of E bit associated address */
+#define SFSR_CTXT(x) (((x)>>4)&0x3)
+#define SFSR_CTXT_IS_PRIM(x) (SFSR_CTXT(x)==0x00)
+#define SFSR_CTXT_IS_SECOND(x) (SFSR_CTXT(x)==0x01)
+#define SFSR_CTXT_IS_NUCLEUS(x) (SFSR_CTXT(x)==0x02)
+#define SFSR_PRIV 0x00008 /* value of PSTATE.PRIV for faulting access */
+#define SFSR_W 0x00004 /* DMMU: attempted write */
+#define SFSR_OW 0x00002 /* Overwrite; prev vault was still valid */
+#define SFSR_FV 0x00001 /* Fault is valid */
+#define SFSR_FT (SFSR_FT_VA_OOR_2|SFSR_FT_VA_OOR_1|SFSR_FT_NFO|SFSR_ILL_ASI|SFSR_FT_IO_ATOMIC|SFSR_FT_ILL_NF|SFSR_FT_PRIV)
+
+#if 0
+/* Old bits */
+#define SFSR_BITS "\40\16VAT\15VAD\14NFO\13ASI\12A\11NF\10PRIV\7E\6NUCLEUS\5SECONDCTX\4PRIV\3W\2OW\1FV"
+#else
+/* New bits */
+#define SFSR_BITS "\177\20" \
+ "f\20\30ASI\0" "b\16VAT\0" "b\15VAD\0" "b\14NFO\0" "b\13ASI\0" "b\12A\0" "b\11NF\0" "b\10PRIV\0" \
+ "b\7E\0" "b\6NUCLEUS\0" "b\5SECONDCTX\0" "b\4PRIV\0" "b\3W\0" "b\2OW\0" "b\1FV\0"
+#endif
+
+/* ASFR bits */
+#define ASFR_ME 0x100000000LL
+#define ASFR_PRIV 0x080000000LL
+#define ASFR_ISAP 0x040000000LL
+#define ASFR_ETP 0x020000000LL
+#define ASFR_IVUE 0x010000000LL
+#define ASFR_TO 0x008000000LL
+#define ASFR_BERR 0x004000000LL
+#define ASFR_LDP 0x002000000LL
+#define ASFR_CP 0x001000000LL
+#define ASFR_WP 0x000800000LL
+#define ASFR_EDP 0x000400000LL
+#define ASFR_UE 0x000200000LL
+#define ASFR_CE 0x000100000LL
+#define ASFR_ETS 0x0000f0000LL
+#define ASFT_P_SYND 0x00000ffffLL
+
+#define AFSR_BITS "\177\20" \
+ "b\40ME\0" "b\37PRIV\0" "b\36ISAP\0" "b\35ETP\0" \
+ "b\34IVUE\0" "b\33TO\0" "b\32BERR\0" "b\31LDP\0" \
+ "b\30CP\0" "b\27WP\0" "b\26EDP\0" "b\25UE\0" \
+ "b\24CE\0" "f\20\4ETS\0" "f\0\20P_SYND\0"
+
+/*
+ * Here's the spitfire TSB control register bits.
+ *
+ * Each TSB entry is 16-bytes wide. The TSB must be size aligned
+ */
+#define TSB_SIZE_512 0x0 /* 8kB, etc. */
+#define TSB_SIZE_1K 0x01
+#define TSB_SIZE_2K 0x02
+#define TSB_SIZE_4K 0x03
+#define TSB_SIZE_8K 0x04
+#define TSB_SIZE_16K 0x05
+#define TSB_SIZE_32K 0x06
+#define TSB_SIZE_64K 0x07
+#define TSB_SPLIT 0x1000
+#define TSB_BASE 0xffffffffffffe000
+
+/* TLB Tag Access bits */
+#define TLB_TAG_ACCESS_VA 0xffffffffffffe000
+#define TLB_TAG_ACCESS_CTX 0x0000000000001fff
+
+/*
+ * TLB demap registers. TTEs are defined in v9pte.h
+ *
+ * Use the address space to select between IMMU and DMMU.
+ * The address of the register selects which context register
+ * to read the ASI from.
+ *
+ * The data stored in the register is interpreted as the VA to
+ * use. The DEMAP_CTX_<> registers ignore the address and demap the
+ * entire ASI.
+ *
+ */
+#define ASI_IMMU_DEMAP 0x57 /* [4u] IMMU TLB demap */
+#define ASI_DMMU_DEMAP 0x5f /* [4u] IMMU TLB demap */
+
+#define DEMAP_PAGE_NUCLEUS ((0x02)<<4) /* Demap page from kernel AS */
+#define DEMAP_PAGE_PRIMARY ((0x00)<<4) /* Demap a page from primary CTXT */
+#define DEMAP_PAGE_SECONDARY ((0x01)<<4) /* Demap page from secondary CTXT (DMMU only) */
+#define DEMAP_CTX_NUCLEUS ((0x06)<<4) /* Demap all of kernel CTXT */
+#define DEMAP_CTX_PRIMARY ((0x04)<<4) /* Demap all of primary CTXT */
+#define DEMAP_CTX_SECONDARY ((0x05)<<4) /* Demap all of secondary CTXT */
+
+/*
+ * Interrupt registers. This really gets hairy.
+ */
+
+/* IRSR -- Interrupt Receive Status Ragister */
+#define ASI_IRSR 0x49
+#define IRSR 0x00
+#define IRSR_BUSY 0x020
+#define IRSR_MID(x) (x&0x1f)
+
+/* IRDR -- Interrupt Receive Data Registers */
+#define ASI_IRDR 0x7f
+#define IRDR_0H 0x40
+#define IRDR_0L 0x48 /* unimplemented */
+#define IRDR_1H 0x50
+#define IRDR_1L 0x58 /* unimplemented */
+#define IRDR_2H 0x60
+#define IRDR_2L 0x68 /* unimplemented */
+#define IRDR_3H 0x70 /* unimplemented */
+#define IRDR_3L 0x78 /* unimplemented */
+
+/* SOFTINT ASRs */
+#define SET_SOFTINT %asr20 /* Sets these bits */
+#define CLEAR_SOFTINT %asr21 /* Clears these bits */
+#define SOFTINT %asr22 /* Reads the register */
+#define TICK_CMPR %asr23
+
+#define TICK_INT 0x01 /* level-14 clock tick */
+#define SOFTINT1 (0x1<<1)
+#define SOFTINT2 (0x1<<2)
+#define SOFTINT3 (0x1<<3)
+#define SOFTINT4 (0x1<<4)
+#define SOFTINT5 (0x1<<5)
+#define SOFTINT6 (0x1<<6)
+#define SOFTINT7 (0x1<<7)
+#define SOFTINT8 (0x1<<8)
+#define SOFTINT9 (0x1<<9)
+#define SOFTINT10 (0x1<<10)
+#define SOFTINT11 (0x1<<11)
+#define SOFTINT12 (0x1<<12)
+#define SOFTINT13 (0x1<<13)
+#define SOFTINT14 (0x1<<14)
+#define SOFTINT15 (0x1<<15)
+
+/* Interrupt Dispatch -- usually reserved for cross-calls */
+#define ASR_IDSR 0x48 /* Interrupt dispatch status reg */
+#define IDSR 0x00
+#define IDSR_NACK 0x02
+#define IDSR_BUSY 0x01
+
+#define ASI_INTERRUPT_DISPATCH 0x77 /* [4u] spitfire interrupt dispatch regs */
+#define IDCR(x) (((x)<<14)&0x70) /* Store anything to this address to dispatch crosscall to CPU (x) */
+#define IDDR_0H 0x40 /* Store data to send in these regs */
+#define IDDR_0L 0x48 /* unimplemented */
+#define IDDR_1H 0x50
+#define IDDR_1L 0x58 /* unimplemented */
+#define IDDR_2H 0x60
+#define IDDR_2L 0x68 /* unimplemented */
+#define IDDR_3H 0x70 /* unimplemented */
+#define IDDR_3L 0x78 /* unimplemented */
+
+/*
+ * Error registers
+ */
+
+/* Since we won't try to fix async errs, we don't care about the bits in the regs */
+#define ASI_AFAR 0x4d /* Asynchronous fault address register */
+#define AFAR 0x00
+#define ASI_AFSR 0x4c /* Asynchronous fault status register */
+#define AFSR 0x00
+
+#define ASI_P_EER 0x4b /* Error enable register */
+#define P_EER 0x00
+#define P_EER_ISAPEN 0x04 /* Enable fatal on ISAP */
+#define P_EER_NCEEN 0x02 /* Enable trap on uncorrectable errs */
+#define P_EER_CEEN 0x01 /* Enable trap on correctable errs */
+
+#define ASI_DATAPATH_READ 0x7f /* Read the regs */
+#define ASI_DATAPATH_WRITE 0x77 /* Write to the regs */
+#define P_DPER_0 0x00 /* Datapath err reg 0 */
+#define P_DPER_1 0x18 /* Datapath err reg 1 */
+#define P_DCR_0 0x20 /* Datapath control reg 0 */
+#define P_DCR_1 0x38 /* Datapath control reg 0 */
+
+
+/* From sparc64/asm.h which I think I'll deprecate since it makes bus.h a pain. */
+
+#ifndef _LOCORE
+/*
+ * GCC __asm constructs for doing assembly stuff.
+ */
+
+/*
+ * ``Routines'' to load and store from/to alternate address space.
+ * The location can be a variable, the asi value (address space indicator)
+ * must be a constant.
+ *
+ * N.B.: You can put as many special functions here as you like, since
+ * they cost no kernel space or time if they are not used.
+ *
+ * These were static inline functions, but gcc screws up the constraints
+ * on the address space identifiers (the "n"umeric value part) because
+ * it inlines too late, so we have to use the funny valued-macro syntax.
+ */
+
+/*
+ * Apparently the definition of bypass ASIs is that they all use the
+ * D$ so we need to flush the D$ to make sure we don't get data pollution.
+ */
+
+static __inline__ u_char lduba __P((paddr_t loc, int asi));
+static __inline__ u_short lduha __P((paddr_t loc, int asi));
+static __inline__ u_int lda __P((paddr_t loc, int asi));
+static __inline__ int ldswa __P((paddr_t loc, int asi));
+static __inline__ u_int64_t ldxa __P((paddr_t loc, int asi));
+static __inline__ u_int64_t ldda __P((paddr_t loc, int asi));
+
+static __inline__ void stba __P((paddr_t loc, int asi, u_char value));
+static __inline__ void stha __P((paddr_t loc, int asi, u_short value));
+static __inline__ void sta __P((paddr_t loc, int asi, u_int value));
+static __inline__ void stxa __P((paddr_t loc, int asi, u_int64_t value));
+static __inline__ void stda __P((paddr_t loc, int asi, u_int64_t value));
+
+#if 0
+static __inline__ unsigned int casa __P((paddr_t loc, int asi,
+ unsigned int value, unsigned int oldvalue));
+static __inline__ u_int64_t casxa __P((paddr_t loc, int asi,
+ u_int64_t value, u_int64_t oldvalue));
+#endif
+
+#ifdef __arch64__
+static __inline__ u_char
+lduba(paddr_t loc, int asi)
+{
+ register unsigned int _lduba_v;
+
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %3,%%g0,%%asi; "
+" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; "
+" lduba [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; "
+" stxa %%g0,[%1] %4; membar #Sync; wr %%g0, 0x82, %%asi" :
+ "=&r" (_lduba_v), "=r" (loc):
+ "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %2,%%g0,%%asi; "
+" lduba [%1]%%asi,%0; wr %%g0, 0x82, %%asi" :
+ "=r" (_lduba_v) :
+ "r" ((unsigned long)(loc)), "r" (asi));
+ }
+ return (_lduba_v);
+}
+#else
+static __inline__ u_char
+lduba(paddr_t loc, int asi)
+{
+ register unsigned int _lduba_v, _loc_hi, _pstate;
+
+ _loc_hi = (((u_int64_t)loc)>>32);
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %4,%%g0,%%asi; "
+" andn %2,0x1f,%0; stxa %%g0,[%0] %5; rdpr %%pstate,%1; "
+" sllx %3,32,%0; or %0,%2,%0; wrpr %1,8,%%pstate; "
+" membar #Sync; lduba [%0]%%asi,%0; wrpr %1,0,%%pstate; "
+" andn %2,0x1f,%1; membar #Sync; stxa %%g0,[%1] %5; "
+" membar #Sync; wr %%g0, 0x82, %%asi" :
+ "=&r" (_lduba_v), "=&r" (_pstate) :
+ "r" ((unsigned long)(loc)), "r" (_loc_hi),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %3,%%g0,%%asi; sllx %2,32,%0; "
+" or %0,%1,%0; lduba [%0]%%asi,%0; wr %%g0, 0x82, %%asi" : "=&r" (_lduba_v) :
+ "r" ((unsigned long)(loc)),
+ "r" (_loc_hi), "r" (asi));
+ }
+ return (_lduba_v);
+}
+#endif
+
+#ifdef __arch64__
+/* load half-word from alternate address space */
+static __inline__ u_short
+lduha(paddr_t loc, int asi)
+{
+ register unsigned int _lduha_v;
+
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %3,%%g0,%%asi; "
+" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; "
+" lduha [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; "
+" stxa %%g0,[%1] %4; membar #Sync; "
+" wr %%g0, 0x82, %%asi" : "=&r" (_lduha_v), "=r" (loc) :
+ "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %2,%%g0,%%asi; lduha [%1]%%asi,%0; "
+" wr %%g0, 0x82, %%asi" :
+ "=r" (_lduha_v) :
+ "r" ((unsigned long)(loc)), "r" (asi));
+ }
+ return (_lduha_v);
+}
+#else
+/* load half-word from alternate address space */
+static __inline__ u_short
+lduha(paddr_t loc, int asi) {
+ register unsigned int _lduha_v, _loc_hi, _pstate;
+
+ _loc_hi = (((u_int64_t)loc)>>32);
+
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %4,%%g0,%%asi; rdpr %%pstate,%1; "
+" andn %2,0x1f,%0; stxa %%g0,[%0] %5; wrpr %1,8,%%pstate; sllx %3,32,%0; "
+" or %0,%2,%0; membar #Sync; lduha [%0]%%asi,%0; wrpr %1,0,%%pstate; "
+" andn %2,0x1f,%1; membar #Sync; stxa %%g0,[%1] %5; "
+" membar #Sync; wr %%g0, 0x82, %%asi" :
+ "=&r" (_lduha_v), "=&r" (_pstate) :
+ "r" ((unsigned long)(loc)), "r" (_loc_hi),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %3,%%g0,%%asi; sllx %2,32,%0; "
+" or %0,%1,%0; lduha [%0]%%asi,%0; wr %%g0, 0x82, %%asi" : "=&r" (_lduha_v) :
+ "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
+ }
+ return (_lduha_v);
+}
+#endif
+
+
+#ifdef __arch64__
+/* load unsigned int from alternate address space */
+static __inline__ u_int
+lda(paddr_t loc, int asi)
+{
+ register unsigned int _lda_v;
+
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %3,%%g0,%%asi; "
+" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; "
+" lda [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; "
+" stxa %%g0,[%1] %4; membar #Sync; "
+" wr %%g0, 0x82, %%asi" : "=&r" (_lda_v), "=r" (loc) :
+ "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %2,%%g0,%%asi; lda [%1]%%asi,%0" :
+ "=r" (_lda_v) :
+ "r" ((unsigned long)(loc)), "r" (asi));
+ }
+ return (_lda_v);
+}
+
+/* load signed int from alternate address space */
+static __inline__ int
+ldswa(paddr_t loc, int asi)
+{
+ register int _lda_v;
+
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %3,%%g0,%%asi; "
+" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; "
+" ldswa [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; "
+" stxa %%g0,[%1] %4; membar #Sync; "
+" wr %%g0, 0x82, %%asi" : "=&r" (_lda_v), "=r" (loc) :
+ "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %2,%%g0,%%asi; "
+" ldswa [%1]%%asi,%0; wr %%g0, 0x82, %%asi" :
+ "=r" (_lda_v) :
+ "r" ((unsigned long)(loc)), "r" (asi));
+ }
+ return (_lda_v);
+}
+#else /* __arch64__ */
+/* load unsigned int from alternate address space */
+static __inline__ u_int
+lda(paddr_t loc, int asi)
+{
+ register unsigned int _lda_v, _loc_hi, _pstate;
+
+ _loc_hi = (((u_int64_t)loc)>>32);
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %4,%%g0,%%asi; rdpr %%pstate,%1;"
+" andn %2,0x1f,%0; stxa %%g0,[%0] %5; wrpr %1,8,%%pstate; "
+" sllx %3,32,%0; or %0,%2,%0; membar #Sync;lda [%0]%%asi,%0; "
+" wrpr %1,0,%%pstate; andn %2,0x1f,%1; membar #Sync; "
+" stxa %%g0,[%1] %5; membar #Sync; "
+" wr %%g0, 0x82, %%asi" : "=&r" (_lda_v), "=&r" (_pstate) :
+ "r" ((unsigned long)(loc)), "r" (_loc_hi),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %3,%%g0,%%asi; sllx %2,32,%0; "
+" or %0,%1,%0; lda [%0]%%asi,%0; wr %%g0, 0x82, %%asi" : "=&r" (_lda_v) :
+ "r" ((unsigned long)(loc)),
+ "r" (_loc_hi), "r" (asi));
+ }
+ return (_lda_v);
+}
+
+/* load signed int from alternate address space */
+static __inline__ int
+ldswa(paddr_t loc, int asi)
+{
+ register int _lda_v, _loc_hi, _pstate;
+
+ _loc_hi = (((u_int64_t)loc)>>32);
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %4,%%g0,%%asi; rdpr %%pstate,%1;"
+" andn %2,0x1f,%0; stxa %%g0,[%0] %5; wrpr %1,8,%%pstate; sllx %3,32,%0;"
+" or %0,%2,%0; membar #Sync; ldswa [%0]%%asi,%0; wrpr %1,0,%%pstate; "
+" andn %2,0x1f,%1; membar #Sync; stxa %%g0,[%1] %5; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (_lda_v), "=&r" (_pstate) :
+ "r" ((unsigned long)(loc)), "r" (_loc_hi),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %3,%%g0,%%asi; sllx %2,32,%0; "
+" or %0,%1,%0; ldswa [%0]%%asi,%0; wr %%g0, 0x82, %%asi" : "=&r" (_lda_v) :
+ "r" ((unsigned long)(loc)),
+ "r" (_loc_hi), "r" (asi));
+ }
+ return (_lda_v);
+}
+#endif /* __arch64__ */
+
+#ifdef __arch64__
+/* load 64-bit int from alternate address space -- these should never be used */
+static __inline__ u_int64_t
+ldda(paddr_t loc, int asi)
+{
+ register long long _lda_v;
+
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %3,%%g0,%%asi; "
+" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; "
+" ldda [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; "
+" stxa %%g0,[%1] %4; membar #Sync; "
+" wr %%g0, 0x82, %%asi" : "=&r" (_lda_v), "=&r" (loc) :
+ "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %2,%%g0,%%asi; "
+" ldda [%1]%%asi,%0; wr %%g0, 0x82, %%asi" :
+ "=r" (_lda_v) :
+ "r" ((unsigned long)(loc)), "r" (asi));
+ }
+ return (_lda_v);
+}
+#else
+/* load 64-bit int from alternate address space */
+static __inline__ u_int64_t
+ldda(paddr_t loc, int asi)
+{
+ register long long _lda_v, _loc_hi, _pstate;
+
+ _loc_hi = (((u_int64_t)loc)>>32);
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %4,%%g0,%%asi; rdpr %%pstate,%1;"
+" andn %2,0x1f,%0; rdpr %%pstate,%1; stxa %%g0,[%0] %5; wrpr %1,8,%%pstate;"
+" sllx %3,32,%0; or %0,%2,%0; membar #Sync; ldda [%0]%%asi,%0; wrpr %1,0,%%pstate; "
+" andn %2,0x1f,%1; membar #Sync; stxa %%g0,[%1] %5; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (_lda_v), "=&r" (_pstate) :
+ "r" ((unsigned long)(loc)), "r" (_loc_hi),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %3,%%g0,%%asi; sllx %2,32,%0; "
+" or %0,%1,%0; ldda [%0]%%asi,%0; wr %%g0, 0x82, %%asi" : "=&r" (_lda_v) :
+ "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
+ }
+ return (_lda_v);
+}
+#endif
+
+
+#ifdef __arch64__
+/* native load 64-bit int from alternate address space w/64-bit compiler*/
+static __inline__ u_int64_t
+ldxa(paddr_t loc, int asi)
+{
+ register unsigned long _lda_v;
+
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %3,%%g0,%%asi; "
+" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; "
+" ldxa [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; "
+" stxa %%g0,[%1] %4; membar #Sync; "
+" wr %%g0, 0x82, %%asi" : "=&r" (_lda_v), "=r" (loc) :
+ "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %2,%%g0,%%asi; "
+" ldxa [%1]%%asi,%0; wr %%g0, 0x82, %%asi" :
+ "=r" (_lda_v) :
+ "r" ((unsigned long)(loc)), "r" (asi));
+ }
+ return (_lda_v);
+}
+#else
+/* native load 64-bit int from alternate address space w/32-bit compiler*/
+static __inline__ u_int64_t
+ldxa(paddr_t loc, int asi)
+{
+ register unsigned long _ldxa_lo, _ldxa_hi, _loc_hi;
+
+ _loc_hi = (((u_int64_t)loc)>>32);
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %4,%%g0,%%asi; "
+" andn %2,0x1f,%0; rdpr %%pstate,%1; stxa %%g0,[%0] %5; "
+" sllx %3,32,%0; wrpr %1,8,%%pstate; or %0,%2,%0; membar #Sync; ldxa [%0]%%asi,%0; "
+" wrpr %1,0,%%pstate; andn %2,0x1f,%1; membar #Sync; stxa %%g0,[%1] %5; membar #Sync; "
+" srlx %0,32,%1; srl %0,0,%0; wr %%g0, 0x82, %%asi" :
+ "=&r" (_ldxa_lo), "=&r" (_ldxa_hi) :
+ "r" ((unsigned long)(loc)), "r" (_loc_hi),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %4,%%g0,%%asi; sllx %3,32,%0; "
+" or %0,%2,%0; ldxa [%0]%%asi,%0; srlx %0,32,%1; "
+" srl %0,0,%0;; wr %%g0, 0x82, %%asi" :
+ "=&r" (_ldxa_lo), "=&r" (_ldxa_hi) :
+ "r" ((unsigned long)(loc)), "r" (_loc_hi),
+ "r" (asi));
+ }
+ return ((((int64_t)_ldxa_hi)<<32)|_ldxa_lo);
+}
+#endif
+
+/* store byte to alternate address space */
+#ifdef __arch64__
+static __inline__ void
+stba(paddr_t loc, int asi, u_char value)
+{
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %3,%%g0,%%asi; stba %1,[%2]%%asi;"
+" andn %2,0x1f,%0; membar #Sync; stxa %%g0,[%0] %4; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (loc) :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %2,%%g0,%%asi; stba %0,[%1]%%asi; "
+" wr %%g0, 0x82, %%asi" : :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (asi));
+ }
+}
+#else
+static __inline__ void
+stba(paddr_t loc, int asi, u_char value)
+{
+ register int _loc_hi, _pstate;
+
+ _loc_hi = (((u_int64_t)loc)>>32);
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %5,%%g0,%%asi; sllx %4,32,%0; rdpr %%pstate,%1;"
+" or %3,%0,%0; wrpr %1,8,%%pstate; stba %2,[%0]%%asi; wrpr %1,0,%%pstate; "
+" andn %0,0x1f,%1; membar #Sync; stxa %%g0,[%1] %6; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (_loc_hi), "=&r" (_pstate) :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (_loc_hi), "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %4,%%g0,%%asi; sllx %3,32,%0; "
+" or %2,%0,%0; stba %1,[%0]%%asi; wr %%g0, 0x82, %%asi" : "=&r" (_loc_hi) :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (_loc_hi), "r" (asi));
+ }
+}
+#endif
+
+/* store half-word to alternate address space */
+#ifdef __arch64__
+static __inline__ void
+stha(paddr_t loc, int asi, u_short value)
+{
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %3,%%g0,%%asi; stha %1,[%2]%%asi;"
+" andn %2,0x1f,%0; membar #Sync; stxa %%g0,[%0] %4; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (loc) :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG) : "memory");
+ } else {
+ __asm __volatile("wr %2,%%g0,%%asi; stha %0,[%1]%%asi; "
+" wr %%g0, 0x82, %%asi" : :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (asi) : "memory");
+ }
+}
+#else
+static __inline__ void
+stha(paddr_t loc, int asi, u_short value)
+{
+ register int _loc_hi, _pstate;
+
+ _loc_hi = (((u_int64_t)loc)>>32);
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %5,%%g0,%%asi; sllx %4,32,%0; rdpr %%pstate,%1;"
+" or %3,%0,%0; wrpr %1,8,%%pstate; stha %2,[%0]%%asi; wrpr %1,0,%%pstate; "
+" andn %0,0x1f,%1; membar #Sync; stxa %%g0,[%1] %6; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (_loc_hi), "=&r" (_pstate) :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (_loc_hi), "r" (asi),
+ "n" (ASI_DCACHE_TAG) : "memory");
+ } else {
+ __asm __volatile("wr %4,%%g0,%%asi; sllx %3,32,%0; "
+" or %2,%0,%0; stha %1,[%0]%%asi; wr %%g0, 0x82, %%asi" : "=&r" (_loc_hi) :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (_loc_hi), "r" (asi) : "memory");
+ }
+}
+#endif
+
+
+/* store int to alternate address space */
+#ifdef __arch64__
+static __inline__ void
+sta(paddr_t loc, int asi, u_int value)
+{
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %3,%%g0,%%asi; sta %1,[%2]%%asi;"
+" andn %2,0x1f,%0; membar #Sync; stxa %%g0,[%0] %4; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (loc) :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG) : "memory");
+ } else {
+ __asm __volatile("wr %2,%%g0,%%asi; sta %0,[%1]%%asi; "
+" wr %%g0, 0x82, %%asi" : :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (asi) : "memory");
+ }
+}
+#else
+static __inline__ void
+sta(paddr_t loc, int asi, u_int value)
+{
+ register int _loc_hi, _pstate;
+
+ _loc_hi = (((u_int64_t)loc)>>32);
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %5,%%g0,%%asi; sllx %4,32,%0; rdpr %%pstate,%1;"
+" or %3,%0,%0; wrpr %1,8,%%pstate; sta %2,[%0]%%asi; wrpr %1,0,%%pstate; "
+" andn %0,0x1f,%1; membar #Sync; stxa %%g0,[%1] %6; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (_loc_hi), "=&r" (_pstate) :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (_loc_hi), "r" (asi),
+ "n" (ASI_DCACHE_TAG) : "memory");
+ } else {
+ __asm __volatile("wr %4,%%g0,%%asi; sllx %3,32,%0; "
+" or %2,%0,%0; sta %1,[%0]%%asi; wr %%g0, 0x82, %%asi" : "=&r" (_loc_hi) :
+ "r" ((int)(value)), "r" ((unsigned long)(loc)),
+ "r" (_loc_hi), "r" (asi) : "memory");
+ }
+}
+#endif
+
+/* store 64-bit int to alternate address space */
+#ifdef __arch64__
+static __inline__ void
+stda(paddr_t loc, int asi, u_int64_t value)
+{
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %3,%%g0,%%asi; stda %1,[%2]%%asi;"
+" andn %2,0x1f,%0; membar #Sync; stxa %%g0,[%0] %4; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (loc) :
+ "r" ((long long)(value)), "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG) : "memory");
+ } else {
+ __asm __volatile("wr %2,%%g0,%%asi; stda %0,[%1]%%asi; "
+" wr %%g0, 0x82, %%asi" : :
+ "r" ((long long)(value)), "r" ((unsigned long)(loc)),
+ "r" (asi) : "memory");
+ }
+}
+#else
+static __inline__ void
+stda(paddr_t loc, int asi, u_int64_t value)
+{
+ register int _loc_hi, _pstate;
+
+ _loc_hi = (((u_int64_t)loc)>>32);
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %5,%%g0,%%asi; sllx %4,32,%0; rdpr %%pstate,%1; "
+" or %3,%0,%0; wrpr %1,8,%%pstate; stda %2,[%0]%%asi; wrpr %1,0,%%pstate;"
+" andn %0,0x1f,%1; membar #Sync; stxa %%g0,[%1] %6; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (_loc_hi), "=&r" (_pstate) :
+ "r" ((long long)(value)), "r" ((unsigned long)(loc)),
+ "r" (_loc_hi), "r" (asi),
+ "n" (ASI_DCACHE_TAG) : "memory");
+ } else {
+ __asm __volatile("wr %4,%%g0,%%asi; sllx %3,32,%0; "
+" or %2,%0,%0; stda %1,[%0]%%asi; wr %%g0, 0x82, %%asi" :
+ "=&r" (_loc_hi) :
+ "r" ((long long)(value)), "r" ((unsigned long)(loc)),
+ "r" (_loc_hi), "r" (asi) : "memory");
+ }
+}
+#endif
+
+#ifdef __arch64__
+/* native store 64-bit int to alternate address space w/64-bit compiler*/
+static __inline__ void
+stxa(paddr_t loc, int asi, u_int64_t value)
+{
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %3,%%g0,%%asi; stxa %1,[%2]%%asi;"
+" andn %2,0x1f,%0; membar #Sync; stxa %%g0,[%0] %4; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (asi) :
+ "r" ((unsigned long)(value)),
+ "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG) : "memory");
+ } else {
+ __asm __volatile("wr %2,%%g0,%%asi; stxa %0,[%1]%%asi; "
+" wr %%g0, 0x82, %%asi" : :
+ "r" ((unsigned long)(value)),
+ "r" ((unsigned long)(loc)), "r" (asi) : "memory");
+ }
+}
+#else
+/* native store 64-bit int to alternate address space w/32-bit compiler*/
+static __inline__ void
+stxa(paddr_t loc, int asi, u_int64_t value)
+{
+ int _stxa_lo, _stxa_hi, _loc_hi;
+
+ _stxa_lo = value;
+ _stxa_hi = ((u_int64_t)value)>>32;
+ _loc_hi = (((u_int64_t)(u_long)loc)>>32);
+
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %7,%%g0,%%asi; sllx %4,32,%1; sllx %6,32,%0; "
+" or %1,%3,%1; rdpr %%pstate,%2; or %0,%5,%0; wrpr %2,8,%%pstate; "
+" stxa %1,[%0]%%asi; wrpr %2,0,%%pstate; andn %0,0x1f,%1; "
+" membar #Sync; stxa %%g0,[%1] %8; membar #Sync; wr %%g0, 0x82, %%asi" :
+ "=&r" (_loc_hi), "=&r" (_stxa_hi),
+ "=&r" ((int)(_stxa_lo)) :
+ "r" ((int)(_stxa_lo)), "r" ((int)(_stxa_hi)),
+ "r" ((unsigned long)(loc)), "r" (_loc_hi),
+ "r" (asi), "n" (ASI_DCACHE_TAG) : "memory");
+ } else {
+ __asm __volatile("wr %6,%%g0,%%asi; sllx %3,32,%1; sllx %5,32,%0; "
+" or %1,%2,%1; or %0,%4,%0; stxa %1,[%0]%%asi; wr %%g0, 0x82, %%asi" :
+ "=&r" (_loc_hi), "=&r" (_stxa_hi) :
+ "r" ((int)(_stxa_lo)), "r" ((int)(_stxa_hi)),
+ "r" ((unsigned long)(loc)), "r" (_loc_hi),
+ "r" (asi) : "memory");
+ }
+}
+#endif
+
+#if 0
+#ifdef __arch64__
+/* native store 64-bit int to alternate address space w/64-bit compiler*/
+static __inline__ u_int64_t
+casxa(paddr_t loc, int asi, u_int64_t value, u_int64_t oldvalue)
+{
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %4,%%g0,%%asi; casxa [%3]%%asi,%2,%1;"
+" andn %3,0x1f,%0; membar #Sync; stxa %%g0,[%0] %5; membar #Sync; "
+" wr %%g0, 0x82, %%asi" :
+ "=&r" (loc), "+r" (value) :
+ "r" ((unsigned long)(oldvalue)),
+ "r" ((unsigned long)(loc)),
+ "r" (asi), "n" (ASI_DCACHE_TAG) : "memory");
+ } else {
+ __asm __volatile("wr %3,%%g0,%%asi; casxa [%1]%%asi,%2,%0; "
+" wr %%g0, 0x82, %%asi" :
+ "+r" (value) :
+ "r" ((unsigned long)(loc)), "r" (oldvalue), "r" (asi) :
+ "memory");
+ }
+ return (value);
+}
+#else
+/* native store 64-bit int to alternate address space w/32-bit compiler*/
+static __inline__ u_int64_t
+casxa(paddr_t loc, int asi, u_int64_t value, u_int64_t oldvalue)
+{
+ int _casxa_lo, _casxa_hi, _loc_hi, _oval_hi;
+
+ _casxa_lo = value;
+ _casxa_hi = ((u_int64_t)value)>>32;
+ _oval_hi = ((u_int64_t)oldvalue)>>32;
+ _loc_hi = (((u_int64_t)(u_long)loc)>>32);
+
+#ifdef __notyet
+/*
+ * gcc cannot handle this since it thinks it has >10 asm operands.
+ */
+ if (PHYS_ASI(asi)) {
+ __asm __volatile("wr %6,%%g0,%%asi; sllx %1,32,%1; sllx %0,32,%0; "
+" sllx %3,32,%3; or %1,%2,%1; rdpr %%pstate,%2; or %0,%4,%0; or %3,%5,%3; "
+" wrpr %2,8,%%pstate; casxa [%0]%%asi,%3,%1; wrpr %2,0,%%pstate; "
+" andn %0,0x1f,%3; membar #Sync; stxa %%g0,[%3] %7; membar #Sync; "
+" sll %1,0,%2; srax %1,32,%1; wr %%g0, 0x82, %%asi " :
+ "+r" (_loc_hi), "+r" (_casxa_hi),
+ "+r" (_casxa_lo), "+r" (_oval_hi) :
+ "r" ((unsigned long)(loc)),
+ "r" ((unsigned int)(oldvalue)),
+ "r" (asi), "n" (ASI_DCACHE_TAG));
+ } else {
+ __asm __volatile("wr %7,%%g0,%%asi; sllx %1,32,%1; sllx %5,32,%0; "
+" or %1,%2,%1; sllx %3,32,%2; or %0,%4,%0; or %2,%4,%2; "
+" casxa [%0]%%asi,%2,%1; sll %1,0,%2; srax %o1,32,%o1; wr %%g0, 0x82, %%asi " :
+ "=&r" (_loc_hi), "+r" (_casxa_hi), "+r" (_casxa_lo) :
+ "r" ((int)(_oval_hi)), "r" ((int)(oldvalue)),
+ "r" ((unsigned long)(loc)), "r" (_loc_hi),
+ "r" (asi) : "memory");
+ }
+#endif
+ return (((u_int64_t)_casxa_hi<<32)|(u_int64_t)_casxa_lo);
+}
+#endif
+#endif /* 0 */
+
+
+
+/* flush address from data cache */
+#define flush(loc) ({ \
+ __asm __volatile("flush %0" : : \
+ "r" ((unsigned long)(loc))); \
+})
+
+/* Flush a D$ line */
+#if 0
+#define flushline(loc) ({ \
+ stxa(((paddr_t)loc)&(~0x1f), (ASI_DCACHE_TAG), 0); \
+ membar_sync(); \
+})
+#else
+#define flushline(loc)
+#endif
+
+/* The following two enable or disable the dcache in the LSU control register */
+#define dcenable() ({ \
+ int res; \
+ __asm __volatile("ldxa [%%g0] %1,%0; or %0,%2,%0; stxa %0,[%%g0] %1; membar #Sync" \
+ : "r" (res) : "n" (ASI_MCCR), "n" (MCCR_DCACHE_EN)); \
+})
+#define dcdisable() ({ \
+ int res; \
+ __asm __volatile("ldxa [%%g0] %1,%0; andn %0,%2,%0; stxa %0,[%%g0] %1; membar #Sync" \
+ : "r" (res) : "n" (ASI_MCCR), "n" (MCCR_DCACHE_EN)); \
+})
+
+/*
+ * SPARC V9 memory barrier instructions.
+ */
+/* Make all stores complete before next store */
+#define membar_storestore() __asm __volatile("membar #StoreStore" : :)
+/* Make all loads complete before next store */
+#define membar_loadstore() __asm __volatile("membar #LoadStore" : :)
+/* Make all stores complete before next load */
+#define membar_storeload() __asm __volatile("membar #StoreLoad" : :)
+/* Make all loads complete before next load */
+#define membar_loadload() __asm __volatile("membar #LoadLoad" : :)
+/* Complete all outstanding memory operations and exceptions */
+#define membar_sync() __asm __volatile("membar #Sync" : :)
+/* Complete all outstanding memory operations */
+#define membar_memissue() __asm __volatile("membar #MemIssue" : :)
+/* Complete all outstanding stores before any new loads */
+#define membar_lookaside() __asm __volatile("membar #Lookaside" : :)
+
+#ifdef __arch64__
+/* read 64-bit %tick register */
+#define tick() ({ \
+ register u_long _tick_tmp; \
+ __asm __volatile("rdpr %%tick, %0" : "=r" (_tick_tmp) :); \
+ _tick_tmp; \
+})
+#else
+/* read 64-bit %tick register on 32-bit system */
+#define tick() ({ \
+ register u_int _tick_hi = 0, _tick_lo = 0; \
+ __asm __volatile("rdpr %%tick, %0; srl %0,0,%1; srlx %0,32,%0 " \
+ : "=r" (_tick_hi), "=r" (_tick_lo) : ); \
+ (((u_int64_t)_tick_hi)<<32)|((u_int64_t)_tick_lo); \
+})
+#endif
+
+extern void next_tick __P((long));
+#endif
diff --git a/sys/arch/sparc64/include/frame.h b/sys/arch/sparc64/include/frame.h
new file mode 100644
index 00000000000..d663cc2fcf4
--- /dev/null
+++ b/sys/arch/sparc64/include/frame.h
@@ -0,0 +1,134 @@
+/* $NetBSD: frame.h,v 1.9 2001/03/04 09:28:35 mrg Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)frame.h 8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * Sparc stack frame format.
+ *
+ * Note that the contents of each stack frame may be held only in
+ * machine register windows. In order to get an accurate picture
+ * of the frame, you must first force the kernel to write any such
+ * windows to the stack.
+ */
+#ifndef _LOCORE
+#ifndef SUN4U
+struct frame {
+ int32_t fr_local[8]; /* space to save locals (%l0..%l7) */
+ int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */
+ struct frame *fr_fp; /* space to save frame pointer (%i6) */
+ int32_t fr_pc; /* space to save return pc (%i7) */
+ /*
+ * SunOS reserves another 8 words here; this is pointless
+ * but we do it for compatibility.
+ */
+ int32_t fr_xxx; /* `structure return pointer' (unused) */
+ int32_t fr_argd[6]; /* `arg dump area' (lunacy) */
+ int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */
+};
+#else
+struct frame32 {
+ int32_t fr_local[8]; /* space to save locals (%l0..%l7) */
+ int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */
+ u_int32_t fr_fp; /* space to save frame pointer (%i6) */
+ u_int32_t fr_pc; /* space to save return pc (%i7) */
+ /*
+ * SunOS reserves another 8 words here; this is pointless
+ * but we do it for compatibility.
+ */
+ int32_t fr_xxx; /* `structure return pointer' (unused) */
+ int32_t fr_argd[6]; /* `arg dump area' (lunacy) */
+ int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */
+};
+#endif
+#endif
+
+/*
+ * CCFSZ (C Compiler Frame SiZe) is the size of a stack frame required if
+ * a function is to call C code. It should be just 64, but Sun defined
+ * their frame with space to hold arguments 0 through 5 (plus some junk),
+ * and varargs routines (such as kprintf) demand this, and gcc uses this
+ * area at times anyway.
+ */
+#define CCFSZ 96
+
+/*
+ * Sparc v9 stack frame format.
+ *
+ * Note that the contents of each stack frame may be held only in
+ * machine register windows. In order to get an accurate picture
+ * of the frame, you must first force the kernel to write any such
+ * windows to the stack.
+ *
+ * V9 frames have an odd bias, so you can tall a v9 frame from
+ * a v8 frame by testing the stack pointer's lsb.
+ */
+#if !defined(_LOCORE) && !defined(_LIBC)
+struct frame64 {
+ int64_t fr_local[8]; /* space to save locals (%l0..%l7) */
+ int64_t fr_arg[6]; /* space to save arguments (%i0..%i5) */
+ u_int64_t fr_fp; /* space to save frame pointer (%i6) */
+ u_int64_t fr_pc; /* space to save return pc (%i7) */
+ /*
+ * SVR4 reserves a bunch of extra stuff.
+ */
+ int64_t fr_argd[6]; /* `register save area' (lunacy) */
+ int64_t fr_argx[0]; /* arg extension (args 7..n; variable size) */
+};
+
+#define v9next_frame(f) ((struct frame64*)(f->fr_fp+BIAS))
+#endif
+
+/*
+ * CC64FSZ (C Compiler 64-bit Frame SiZe) is the size of a stack frame used
+ * by the compiler in 64-bit mode. It is (16)*8; space for 8 ins, 8 outs.
+ */
+#define CC64FSZ 176
+
+/*
+ * v9 stacks all have a bias of 2047 added to the %sp and %fp, so you can easily
+ * detect it by testing the register for an odd value. Why 2K-1 I don't know.
+ */
+#define BIAS (2048-1)
+
diff --git a/sys/arch/sparc64/include/trap.h b/sys/arch/sparc64/include/trap.h
new file mode 100644
index 00000000000..c2efbd6781c
--- /dev/null
+++ b/sys/arch/sparc64/include/trap.h
@@ -0,0 +1,152 @@
+/* $NetBSD: trap.h,v 1.4 1999/06/07 05:28:04 eeh Exp $ */
+
+/*
+ * 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.
+ *
+ */
+
+
+#ifndef _MACHINE_TRAP_H
+#define _MACHINE_TRAP_H
+
+/* trap vec (pri) description */
+/* 0x000 unused */
+#define T_POR 0x001 /* (0) power on reset */
+#define T_WDR 0x002 /* (1) watchdog reset */
+#define T_XIR 0x003 /* (1) externally initiated reset */
+#define T_SIR 0x004 /* (1) software initiated reset */
+#define T_RED_EXCEPTION 0x005 /* (1) RED state exception */
+/* 0x006 unused */
+/* 0x007 unused */
+#define T_INST_EXCEPT 0x008 /* (5) instruction access exception */
+#define T_TEXTFAULT 0x009 /* (2) ? Text fault */
+#define T_INST_ERROR 0x00a /* (3) instruction access error */
+/* 0x00b unused */
+/* through 0x00f unused */
+#define T_ILLINST 0x010 /* (7) illegal instruction */
+#define T_PRIVINST 0x011 /* (6) privileged opcode */
+/* 0x012 unused */
+/* through 0x01f unused */
+#define T_FPDISABLED 0x020 /* (8) fpu disabled */
+#define T_FP_IEEE_754 0x021 /* (11) ieee 754 exception */
+#define T_FP_OTHER 0x022 /* (11) other fp exception */
+#define T_TAGOF 0x023 /* (14) tag overflow */
+#define T_CLEAN_WINDOW 0x024 /* (10) clean window exception */
+/* through 0x027 unused */
+#define T_DIV0 0x028 /* (15) division routine was handed 0 */
+/* 0x02a unused */
+/* through 0x02f unused */
+#define T_DATAFAULT 0x030 /* (12) address fault during data fetch */
+/* 0x031 unused */
+#define T_DATA_ERROR 0x032
+#define T_DATA_PROT 0x033 /* Data protection ??? */
+#define T_ALIGN 0x034 /* (10) address not properly aligned */
+#define T_LDDF_ALIGN 0x035 /* (10) LDDF address not properly aligned */
+#define T_STDF_ALIGN 0x036 /* (10) STDF address not properly aligned */
+#define T_PRIVACT 0x037 /* (11) privileged action */
+/* 0x038 unused */
+/* through 0x03F unused */
+#define T_ASYNC_ERROR 0x040 /* ???? */
+#define T_L1INT 0x041 /* (31) level 1 interrupt */
+#define T_L2INT 0x042 /* (30) level 2 interrupt */
+#define T_L3INT 0x043 /* (29) level 3 interrupt */
+#define T_L4INT 0x044 /* (28) level 4 interrupt */
+#define T_L5INT 0x045 /* (27) level 5 interrupt */
+#define T_L6INT 0x046 /* (26) level 6 interrupt */
+#define T_L7INT 0x047 /* (25) level 7 interrupt */
+#define T_L8INT 0x048 /* (24) level 8 interrupt */
+#define T_L9INT 0x049 /* (23) level 9 interrupt */
+#define T_L10INT 0x04a /* (22) level 10 interrupt */
+#define T_L11INT 0x04b /* (21) level 11 interrupt */
+#define T_L12INT 0x04c /* (20) level 12 interrupt */
+#define T_L13INT 0x04d /* (19) level 13 interrupt */
+#define T_L14INT 0x04e /* (18) level 14 interrupt */
+#define T_L15INT 0x04f /* (17) level 15 interrupt */
+/* 0x050 unused */
+/* through 0x05F unused */
+#define T_INTVEC 0x060 /* (16) interrupt vector [Interrupt Global Regs]*/
+#define T_PA_WATCHPT 0x061 /* (12) Physical addr data watchpoint */
+#define T_VA_WATCHPT 0x062 /* (11) Virtual addr data watchpoint */
+#define T_ECCERR 0x063 /* (33) ECC correction error */
+#define T_FIMMU_MISS 0x064 /* (2) fast instruction access MMU miss */
+/* through 0x067 unused */
+#define T_FDMMU_MISS 0x068 /* (2) fast data access MMU miss */
+/* through 0x06b unused */
+#define T_FDMMU_PROT 0x06C /* (2) fast data access protection */
+/* through 0x06F unused */
+/* 0x070...0x07f implementation dependent exceptions */
+#define T_SPILL_N_NORM 0x080 /* (9) spill (n=0..7) normal */
+/* through 0x09F unused */
+#define T_SPILL_N_OTHER 0x0a0 /* (9) spill (n=0..7) other */
+/* through 0x0bF unused */
+#define T_FILL_N_NORM 0x0c0 /* (9) fill (n=0..7) normal */
+/* through 0x0dF unused */
+#define T_FILL_N_OTHER 0x0e0 /* (9) fill (n=0..7) other */
+/* through 0x0fF unused */
+
+/* beginning of `user' vectors (from trap instructions) - all priority 16 */
+#define T_SUN_SYSCALL 0x100 /* system call */
+#define T_BREAKPOINT 0x101 /* breakpoint `instruction' */
+#define T_UDIV0 0x102 /* division routine was handed 0 */
+#define T_FLUSHWIN 0x103 /* flush windows */
+#define T_CLEANWIN 0x104 /* provide clean windows */
+#define T_RANGECHECK 0x105 /* ? */
+#define T_FIXALIGN 0x106 /* fix up unaligned accesses */
+#define T_INTOF 0x107 /* integer overflow ? */
+#define T_SVR4_SYSCALL 0x108 /* SVR4 system call */
+#define T_BSD_SYSCALL 0x109 /* BSD system call */
+#define T_KGDB_EXEC 0x10a /* for kernel gdb */
+
+/* 0x10b..0x1ff are currently unallocated, except the following */
+#define T_SVR4_GETCC 0x120
+#define T_SVR4_SETCC 0x121
+#define T_SVR4_GETPSR 0x122
+#define T_SVR4_SETPSR 0x123
+#define T_SVR4_GETHRTIME 0x124
+#define T_SVR4_GETHRVTIME 0x125
+#define T_SVR4_GETHRESTIME 0x127
+#define T_GETCC 0x132
+#define T_SETCC 0x133
+#define T_SVID_SYSCALL 0x164
+#define T_SPARC_INTL_SYSCALL 0x165
+#define T_OS_VENDOR_SYSCALL 0x166
+#define T_HW_OEM_SYSCALL 0x167
+#define T_RTF_DEF_TRAP 0x168
+
+#ifdef _KERNEL /* pseudo traps for locore.s */
+#define T_RWRET -1 /* need first user window for trap return */
+#define T_AST -2 /* no-op, just needed reschedule or profile */
+#endif
+
+/* flags to system call (flags in %g1 along with syscall number) */
+#define SYSCALL_G2RFLAG 0x400 /* on success, return to %g2 rather than npc */
+#define SYSCALL_G7RFLAG 0x800 /* use %g7 as above (deprecated) */
+
+/*
+ * `software trap' macros to keep people happy (sparc v8 manual says not
+ * to set the upper bits).
+ */
+#define ST_BREAKPOINT (T_BREAKPOINT & 0x7f)
+#define ST_DIV0 (T_DIV0 & 0x7f)
+#define ST_FLUSHWIN (T_FLUSHWIN & 0x7f)
+#define ST_SYSCALL (T_SUN_SYSCALL & 0x7f)
+
+#endif /* _MACHINE_TRAP_H_ */