summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-10-06 21:02:56 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-10-06 21:02:56 +0000
commitf2984aabfd358ae2731013df5d571a596cb9a5eb (patch)
tree0b36a098a4b5fcb0d202c68c5a85123e7d95f419 /sys
parentb50063e7723d8a96f3eaeb641e59f7f161dcd917 (diff)
Preliminary bits for SuperH-based ports, based on NetBSD/sh3 codebase with
minor changes.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sh/conf/files.sh31
-rw-r--r--sys/arch/sh/conf/files.shb13
-rw-r--r--sys/arch/sh/conf/files.shpcic10
-rw-r--r--sys/arch/sh/dev/pcicreg.h141
-rw-r--r--sys/arch/sh/dev/scif.c1398
-rw-r--r--sys/arch/sh/dev/scifreg.h164
-rw-r--r--sys/arch/sh/dev/scireg.h82
-rw-r--r--sys/arch/sh/dev/shb.c91
-rw-r--r--sys/arch/sh/dev/shpcic.c1182
-rw-r--r--sys/arch/sh/dev/shpcicvar.h184
-rw-r--r--sys/arch/sh/include/_types.h121
-rw-r--r--sys/arch/sh/include/asm.h217
-rw-r--r--sys/arch/sh/include/bscreg.h70
-rw-r--r--sys/arch/sh/include/cache.h194
-rw-r--r--sys/arch/sh/include/cache_sh3.h159
-rw-r--r--sys/arch/sh/include/cache_sh4.h155
-rw-r--r--sys/arch/sh/include/cdefs.h19
-rw-r--r--sys/arch/sh/include/clock.h90
-rw-r--r--sys/arch/sh/include/cpgreg.h48
-rw-r--r--sys/arch/sh/include/cpu.h213
-rw-r--r--sys/arch/sh/include/cputypes.h79
-rw-r--r--sys/arch/sh/include/db_machdep.h83
-rw-r--r--sys/arch/sh/include/devreg.h83
-rw-r--r--sys/arch/sh/include/disklabel.h112
-rw-r--r--sys/arch/sh/include/endian.h43
-rw-r--r--sys/arch/sh/include/exec.h70
-rw-r--r--sys/arch/sh/include/float.h76
-rw-r--r--sys/arch/sh/include/frame.h130
-rw-r--r--sys/arch/sh/include/ieee.h132
-rw-r--r--sys/arch/sh/include/ieeefp.h27
-rw-r--r--sys/arch/sh/include/intcreg.h127
-rw-r--r--sys/arch/sh/include/internal_types.h6
-rw-r--r--sys/arch/sh/include/intr.h145
-rw-r--r--sys/arch/sh/include/limits.h57
-rw-r--r--sys/arch/sh/include/lock.h87
-rw-r--r--sys/arch/sh/include/locore.h207
-rw-r--r--sys/arch/sh/include/mmu.h115
-rw-r--r--sys/arch/sh/include/mmu_sh3.h90
-rw-r--r--sys/arch/sh/include/mmu_sh4.h154
-rw-r--r--sys/arch/sh/include/param.h137
-rw-r--r--sys/arch/sh/include/pcb.h55
-rw-r--r--sys/arch/sh/include/pmap.h91
-rw-r--r--sys/arch/sh/include/proc.h69
-rw-r--r--sys/arch/sh/include/profile.h74
-rw-r--r--sys/arch/sh/include/psl.h76
-rw-r--r--sys/arch/sh/include/pte.h99
-rw-r--r--sys/arch/sh/include/ptrace.h40
-rw-r--r--sys/arch/sh/include/reg.h103
-rw-r--r--sys/arch/sh/include/rtcreg.h106
-rw-r--r--sys/arch/sh/include/setjmp.h23
-rw-r--r--sys/arch/sh/include/sh_opcode.h163
-rw-r--r--sys/arch/sh/include/signal.h80
-rw-r--r--sys/arch/sh/include/spinlock.h52
-rw-r--r--sys/arch/sh/include/stdarg.h60
-rw-r--r--sys/arch/sh/include/tmureg.h115
-rw-r--r--sys/arch/sh/include/trap.h187
-rw-r--r--sys/arch/sh/include/ubcreg.h86
-rw-r--r--sys/arch/sh/include/userret.h94
-rw-r--r--sys/arch/sh/include/varargs.h57
-rw-r--r--sys/arch/sh/include/vmparam.h107
-rw-r--r--sys/arch/sh/sh/cache.c173
-rw-r--r--sys/arch/sh/sh/cache_sh3.c246
-rw-r--r--sys/arch/sh/sh/cache_sh4.c470
-rw-r--r--sys/arch/sh/sh/clock.c478
-rw-r--r--sys/arch/sh/sh/cpu.c79
-rw-r--r--sys/arch/sh/sh/db_disasm.c1671
-rw-r--r--sys/arch/sh/sh/db_interface.c641
-rw-r--r--sys/arch/sh/sh/db_memrw.c94
-rw-r--r--sys/arch/sh/sh/db_trace.c225
-rw-r--r--sys/arch/sh/sh/devreg.c167
-rw-r--r--sys/arch/sh/sh/genassym.cf120
-rw-r--r--sys/arch/sh/sh/in_cksum.S279
-rw-r--r--sys/arch/sh/sh/interrupt.c752
-rw-r--r--sys/arch/sh/sh/locore_c.c286
-rw-r--r--sys/arch/sh/sh/locore_subr.S866
-rw-r--r--sys/arch/sh/sh/mem.c260
-rw-r--r--sys/arch/sh/sh/mmu.c110
-rw-r--r--sys/arch/sh/sh/mmu_sh3.c136
-rw-r--r--sys/arch/sh/sh/mmu_sh4.c184
-rw-r--r--sys/arch/sh/sh/pmap.c1029
-rw-r--r--sys/arch/sh/sh/process_machdep.c210
-rw-r--r--sys/arch/sh/sh/sh_machdep.c471
-rw-r--r--sys/arch/sh/sh/sys_machdep.c87
-rw-r--r--sys/arch/sh/sh/trap.c618
-rw-r--r--sys/arch/sh/sh/vectors.S275
-rw-r--r--sys/arch/sh/sh/vm_machdep.c364
86 files changed, 18570 insertions, 0 deletions
diff --git a/sys/arch/sh/conf/files.sh b/sys/arch/sh/conf/files.sh
new file mode 100644
index 00000000000..3c45db7852b
--- /dev/null
+++ b/sys/arch/sh/conf/files.sh
@@ -0,0 +1,31 @@
+# $OpenBSD: files.sh,v 1.1 2006/10/06 21:02:55 miod Exp $
+# $NetBSD: files.sh3,v 1.32 2005/12/11 12:18:58 christos Exp $
+
+file arch/sh/sh/cache.c
+file arch/sh/sh/cache_sh3.c sh3
+file arch/sh/sh/cache_sh4.c sh4
+file arch/sh/sh/clock.c
+file arch/sh/sh/db_disasm.c ddb
+file arch/sh/sh/db_interface.c ddb
+file arch/sh/sh/db_memrw.c ddb
+file arch/sh/sh/db_trace.c ddb
+file arch/sh/sh/devreg.c sh3 & sh4
+file arch/sh/sh/interrupt.c
+file arch/sh/sh/locore_c.c
+file arch/sh/sh/locore_subr.S
+file arch/sh/sh/mem.c
+file arch/sh/sh/mmu.c
+file arch/sh/sh/mmu_sh3.c sh3
+file arch/sh/sh/mmu_sh4.c sh4
+file arch/sh/sh/pmap.c
+file arch/sh/sh/process_machdep.c
+file arch/sh/sh/sh_machdep.c
+file arch/sh/sh/sys_machdep.c
+file arch/sh/sh/trap.c
+file arch/sh/sh/vectors.S
+file arch/sh/sh/vm_machdep.c
+
+file arch/sh/sh/in_cksum.S inet
+file netinet/in4_cksum.c inet
+
+file dev/cninit.c
diff --git a/sys/arch/sh/conf/files.shb b/sys/arch/sh/conf/files.shb
new file mode 100644
index 00000000000..13537c21ccc
--- /dev/null
+++ b/sys/arch/sh/conf/files.shb
@@ -0,0 +1,13 @@
+# $OpenBSD: files.shb,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $
+# $NetBSD: files.shb,v 1.4 2005/12/11 12:18:58 christos Exp $
+#
+# SuperH internal devices.
+#
+device shb { }
+attach shb at mainbus
+
+file arch/sh/dev/shb.c shb
+
+device scif: tty
+attach scif at shb
+file arch/sh/dev/scif.c scif needs-flag
diff --git a/sys/arch/sh/conf/files.shpcic b/sys/arch/sh/conf/files.shpcic
new file mode 100644
index 00000000000..054f7d9b611
--- /dev/null
+++ b/sys/arch/sh/conf/files.shpcic
@@ -0,0 +1,10 @@
+# $OpenBSD: files.shpcic,v 1.1 2006/10/06 21:02:55 miod Exp $
+# $NetBSD: files.shpcic,v 1.2 2005/12/11 12:18:58 christos Exp $
+
+#
+# SH7751{,R} integrated PCI controller
+#
+device shpcic: pcibus
+attach shpcic at mainbus
+
+file arch/sh/dev/shpcic.c sh4 & shpcic
diff --git a/sys/arch/sh/dev/pcicreg.h b/sys/arch/sh/dev/pcicreg.h
new file mode 100644
index 00000000000..f4ed0e3c75d
--- /dev/null
+++ b/sys/arch/sh/dev/pcicreg.h
@@ -0,0 +1,141 @@
+/* $OpenBSD: pcicreg.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: pcicreg.h,v 1.2 2005/12/11 12:18:58 christos Exp $ */
+
+/*-
+ * Copyright (c) 2005 NONAKA Kimihiro
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sh/devreg.h>
+
+/*
+ * PCI Controller
+ */
+
+#define SH4_PCIC 0xfe200000
+
+#define SH4_PCIC_IO 0xfe240000
+#define SH4_PCIC_IO_SIZE 0x00040000
+#define SH4_PCIC_IO_MASK (SH4_PCIC_IO_SIZE-1)
+#define SH4_PCIC_MEM 0xfd000000
+#define SH4_PCIC_MEM_SIZE 0x01000000
+#define SH4_PCIC_MEM_MASK (SH4_PCIC_MEM_SIZE-1)
+
+#define SH4_PCICONF (SH4_PCIC+0x000) /* 32bit */
+#define SH4_PCICONF0 (SH4_PCICONF+0x00) /* 32bit */
+#define SH4_PCICONF1 (SH4_PCICONF+0x04) /* 32bit */
+#define SH4_PCICONF2 (SH4_PCICONF+0x08) /* 32bit */
+#define SH4_PCICONF3 (SH4_PCICONF+0x0c) /* 32bit */
+#define SH4_PCICONF4 (SH4_PCICONF+0x10) /* 32bit */
+#define SH4_PCICONF5 (SH4_PCICONF+0x14) /* 32bit */
+#define SH4_PCICONF6 (SH4_PCICONF+0x18) /* 32bit */
+#define SH4_PCICONF7 (SH4_PCICONF+0x1c) /* 32bit */
+#define SH4_PCICONF8 (SH4_PCICONF+0x20) /* 32bit */
+#define SH4_PCICONF9 (SH4_PCICONF+0x24) /* 32bit */
+#define SH4_PCICONF10 (SH4_PCICONF+0x28) /* 32bit */
+#define SH4_PCICONF11 (SH4_PCICONF+0x2c) /* 32bit */
+#define SH4_PCICONF12 (SH4_PCICONF+0x30) /* 32bit */
+#define SH4_PCICONF13 (SH4_PCICONF+0x34) /* 32bit */
+#define SH4_PCICONF14 (SH4_PCICONF+0x38) /* 32bit */
+#define SH4_PCICONF15 (SH4_PCICONF+0x3c) /* 32bit */
+#define SH4_PCICONF16 (SH4_PCICONF+0x40) /* 32bit */
+#define SH4_PCICONF17 (SH4_PCICONF+0x44) /* 32bit */
+#define SH4_PCICR (SH4_PCIC+0x100) /* 32bit */
+#define SH4_PCILSR0 (SH4_PCIC+0x104) /* 32bit */
+#define SH4_PCILSR1 (SH4_PCIC+0x108) /* 32bit */
+#define SH4_PCILAR0 (SH4_PCIC+0x10c) /* 32bit */
+#define SH4_PCILAR1 (SH4_PCIC+0x110) /* 32bit */
+#define SH4_PCIINT (SH4_PCIC+0x114) /* 32bit */
+#define SH4_PCIINTM (SH4_PCIC+0x118) /* 32bit */
+#define SH4_PCIALR (SH4_PCIC+0x11c) /* 32bit */
+#define SH4_PCICLR (SH4_PCIC+0x120) /* 32bit */
+#define SH4_PCIAINT (SH4_PCIC+0x130) /* 32bit */
+#define SH4_PCIAINTM (SH4_PCIC+0x134) /* 32bit */
+#define SH4_PCIDMABT (SH4_PCIC+0x140) /* 32bit */
+#define SH4_PCIDPA0 (SH4_PCIC+0x180) /* 32bit */
+#define SH4_PCIDLA0 (SH4_PCIC+0x184) /* 32bit */
+#define SH4_PCIDTC0 (SH4_PCIC+0x188) /* 32bit */
+#define SH4_PCIDCR0 (SH4_PCIC+0x18c) /* 32bit */
+#define SH4_PCIDPA1 (SH4_PCIC+0x190) /* 32bit */
+#define SH4_PCIDLA1 (SH4_PCIC+0x194) /* 32bit */
+#define SH4_PCIDTC1 (SH4_PCIC+0x198) /* 32bit */
+#define SH4_PCIDCR1 (SH4_PCIC+0x19c) /* 32bit */
+#define SH4_PCIDPA2 (SH4_PCIC+0x1a0) /* 32bit */
+#define SH4_PCIDLA2 (SH4_PCIC+0x1a4) /* 32bit */
+#define SH4_PCIDTC2 (SH4_PCIC+0x1a8) /* 32bit */
+#define SH4_PCIDCR2 (SH4_PCIC+0x1ac) /* 32bit */
+#define SH4_PCIDPA3 (SH4_PCIC+0x1b0) /* 32bit */
+#define SH4_PCIDLA3 (SH4_PCIC+0x1b4) /* 32bit */
+#define SH4_PCIDTC3 (SH4_PCIC+0x1b8) /* 32bit */
+#define SH4_PCIDCR3 (SH4_PCIC+0x1bc) /* 32bit */
+#define SH4_PCIPAR (SH4_PCIC+0x1c0) /* 32bit */
+#define SH4_PCIMBR (SH4_PCIC+0x1c4) /* 32bit */
+#define SH4_PCIIOBR (SH4_PCIC+0x1c8) /* 32bit */
+#define SH4_PCIPINT (SH4_PCIC+0x1cc) /* 32bit */
+#define SH4_PCIPINTM (SH4_PCIC+0x1d0) /* 32bit */
+#define SH4_PCICLKR (SH4_PCIC+0x1d4) /* 32bit */
+#define SH4_PCIBCR1 (SH4_PCIC+0x1e0) /* 32bit */
+#define SH4_PCIBCR2 (SH4_PCIC+0x1e4) /* 32bit */
+#define SH4_PCIWCR1 (SH4_PCIC+0x1e8) /* 32bit */
+#define SH4_PCIWCR2 (SH4_PCIC+0x1ec) /* 32bit */
+#define SH4_PCIWCR3 (SH4_PCIC+0x1f0) /* 32bit */
+#define SH4_PCIMCR (SH4_PCIC+0x1f4) /* 32bit */
+#define SH4_PCIBCR3 (SH4_PCIC+0x1f8) /* 32bit: SH7751R */
+#define SH4_PCIPCTR (SH4_PCIC+0x200) /* 32bit */
+#define SH4_PCIPDTR (SH4_PCIC+0x204) /* 32bit */
+#define SH4_PCIPDR (SH4_PCIC+0x220) /* 32bit */
+
+#define PCICR_BASE 0xa5000000
+#define PCICR_TRDSGL 0x00000200
+#define PCICR_BYTESWAP 0x00000100
+#define PCICR_PCIPUP 0x00000080
+#define PCICR_BMABT 0x00000040
+#define PCICR_MD10 0x00000020
+#define PCICR_MD9 0x00000010
+#define PCICR_SERR 0x00000008
+#define PCICR_INTA 0x00000004
+#define PCICR_RSTCTL 0x00000002
+#define PCICR_CFINIT 0x00000001
+
+#define PCIINT_M_LOCKON 0x00008000
+#define PCIINT_T_TGT_ABORT 0x00004000
+#define PCIINT_TGT_RETRY 0x00000200
+#define PCIINT_MST_DIS 0x00000100
+#define PCIINT_ADRPERR 0x00000080
+#define PCIINT_SERR_DET 0x00000040
+#define PCIINT_T_DPERR_WT 0x00000020
+#define PCIINT_T_PERR_DET 0x00000010
+#define PCIINT_M_TGT_ABORT 0x00000008
+#define PCIINT_M_MST_ABORT 0x00000004
+#define PCIINT_M_DPERR_WT 0x00000002
+#define PCIINT_M_DPERR_RD 0x00000001
+#define PCIINT_ALL 0x0000c3ff
+#define PCIINT_CLEAR_ALL PCIINT_ALL
+
+#define PCIINTM_MASK_ALL 0x00000000
+#define PCIINTM_UNMASK_ALL PCIINT_ALL
+
+#define PCIMBR_MASK 0xff000000
+
+#define PCIIOBR_MASK 0xffc00000
diff --git a/sys/arch/sh/dev/scif.c b/sys/arch/sh/dev/scif.c
new file mode 100644
index 00000000000..c2449a8cbd4
--- /dev/null
+++ b/sys/arch/sh/dev/scif.c
@@ -0,0 +1,1398 @@
+/* $OpenBSD: scif.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: scif.c,v 1.47 2006/07/23 22:06:06 ad Exp $ */
+
+/*-
+ * Copyright (C) 1999 T.Horiuchi and SAITOH Masanobu. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ *
+ * @(#)com.c 7.5 (Berkeley) 5/16/91
+ */
+
+/*
+ * SH internal serial driver
+ *
+ * This code is derived from both z8530tty.c and com.c
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/tty.h>
+#include <sys/proc.h>
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/syslog.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/timeout.h>
+
+#include <dev/cons.h>
+
+#include <sh/clock.h>
+#include <sh/trap.h>
+#include <machine/intr.h>
+
+#include <sh/dev/scifreg.h>
+
+#ifdef DDB
+#include <ddb/db_var.h>
+#endif
+
+void scifstart(struct tty *);
+int scifparam(struct tty *, struct termios *);
+
+void scifcnprobe(struct consdev *);
+void scifcninit(struct consdev *);
+void scifcnputc(dev_t, int);
+int scifcngetc(dev_t);
+void scifcnpoolc(dev_t, int);
+void scif_intr_init(void);
+int scifintr(void *);
+
+struct scif_softc {
+ struct device sc_dev; /* boilerplate */
+ struct tty *sc_tty;
+ void *sc_si;
+
+ struct timeout sc_diag_tmo;
+
+#if 0
+ bus_space_tag_t sc_iot; /* ISA i/o space identifier */
+ bus_space_handle_t sc_ioh; /* ISA io handle */
+
+ int sc_drq;
+
+ int sc_frequency;
+#endif
+
+ u_int sc_overflows,
+ sc_floods,
+ sc_errors; /* number of retries so far */
+ u_char sc_status[7]; /* copy of registers */
+
+ int sc_hwflags;
+ int sc_swflags;
+ u_int sc_fifolen;
+
+ u_int sc_r_hiwat,
+ sc_r_lowat;
+ u_char *volatile sc_rbget,
+ *volatile sc_rbput;
+ volatile u_int sc_rbavail;
+ u_char *sc_rbuf,
+ *sc_ebuf;
+
+ u_char *sc_tba; /* transmit buffer address */
+ u_int sc_tbc, /* transmit byte count */
+ sc_heldtbc;
+
+ volatile u_char sc_rx_flags,
+#define RX_TTY_BLOCKED 0x01
+#define RX_TTY_OVERFLOWED 0x02
+#define RX_IBUF_BLOCKED 0x04
+#define RX_IBUF_OVERFLOWED 0x08
+#define RX_ANY_BLOCK 0x0f
+ sc_tx_busy, /* working on an output chunk */
+ sc_tx_done, /* done with one output chunk */
+ sc_tx_stopped, /* H/W level stop (lost CTS) */
+ sc_st_check, /* got a status interrupt */
+ sc_rx_ready;
+
+ volatile u_char sc_heldchange;
+};
+
+/* controller driver configuration */
+int scif_match(struct device *, void *, void *);
+void scif_attach(struct device *, struct device *, void *);
+
+void scif_break(struct scif_softc *, int);
+void scif_iflush(struct scif_softc *);
+
+void scifsoft(void *);
+void scif_rxsoft(struct scif_softc *, struct tty *);
+void scif_txsoft(struct scif_softc *, struct tty *);
+void scif_stsoft(struct scif_softc *, struct tty *);
+void scif_schedrx(struct scif_softc *);
+void scifdiag(void *);
+
+
+#define SCIFUNIT_MASK 0x7ffff
+#define SCIFDIALOUT_MASK 0x80000
+
+#define SCIFUNIT(x) (minor(x) & SCIFUNIT_MASK)
+#define SCIFDIALOUT(x) (minor(x) & SCIFDIALOUT_MASK)
+
+/* Hardware flag masks */
+#define SCIF_HW_NOIEN 0x01
+#define SCIF_HW_FIFO 0x02
+#define SCIF_HW_FLOW 0x08
+#define SCIF_HW_DEV_OK 0x20
+#define SCIF_HW_CONSOLE 0x40
+
+/* Buffer size for character buffer */
+#define SCIF_RING_SIZE 2048
+
+/* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
+u_int scif_rbuf_hiwat = (SCIF_RING_SIZE * 1) / 4;
+u_int scif_rbuf_lowat = (SCIF_RING_SIZE * 3) / 4;
+
+#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
+int scifconscflag = CONMODE;
+int scifisconsole = 0;
+
+#ifdef SCIFCN_SPEED
+unsigned int scifcn_speed = SCIFCN_SPEED;
+#else
+unsigned int scifcn_speed = 9600;
+#endif
+
+#define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
+
+u_int scif_rbuf_size = SCIF_RING_SIZE;
+
+struct cfattach scif_ca = {
+ sizeof(struct scif_softc), scif_match, scif_attach
+};
+
+struct cfdriver scif_cd = {
+ 0, "scif", DV_DULL
+};
+
+static int scif_attached;
+
+cdev_decl(scif);
+
+void InitializeScif(unsigned int);
+
+/*
+ * following functions are debugging prupose only
+ */
+#define CR 0x0D
+#define USART_ON (unsigned int)~0x08
+
+void scif_putc(unsigned char);
+unsigned char scif_getc(void);
+int ScifErrCheck(void);
+
+
+/* XXX: uwe
+ * Prepare for bus_spacification. The difference in access widths is
+ * still handled by the magic definitions in scifreg.h
+ */
+#define scif_smr_read() SHREG_SCSMR2
+#define scif_smr_write(v) (SHREG_SCSMR2 = (v))
+
+#define scif_brr_read() SHREG_SCBRR2
+#define scif_brr_write(v) (SHREG_SCBRR2 = (v))
+
+#define scif_scr_read() SHREG_SCSCR2
+#define scif_scr_write(v) (SHREG_SCSCR2 = (v))
+
+#define scif_ftdr_write(v) (SHREG_SCFTDR2 = (v))
+
+#define scif_ssr_read() SHREG_SCSSR2
+#define scif_ssr_write(v) (SHREG_SCSSR2 = (v))
+
+#define scif_frdr_read() SHREG_SCFRDR2
+
+#define scif_fcr_read() SHREG_SCFCR2
+#define scif_fcr_write(v) (SHREG_SCFCR2 = (v))
+
+#define scif_fdr_read() SHREG_SCFDR2
+
+#ifdef SH4 /* additional registers in sh4 */
+
+#define scif_sptr_read() SHREG_SCSPTR2
+#define scif_sptr_write(v) (SHREG_SCSPTR2 = (v))
+
+#define scif_lsr_read() SHREG_SCLSR2
+#define scif_lsr_write(v) (SHREG_SCLSR2 = (v))
+
+#endif /* SH4 */
+
+
+/*
+ * InitializeScif
+ * : unsigned int bps;
+ * : SCIF(Serial Communication Interface)
+ */
+
+void
+InitializeScif(unsigned int bps)
+{
+ /* Initialize SCR */
+ scif_scr_write(0x00);
+
+#if 0
+ scif_fcr_write(SCFCR2_TFRST | SCFCR2_RFRST | SCFCR2_MCE);
+#else
+ scif_fcr_write(SCFCR2_TFRST | SCFCR2_RFRST);
+#endif
+ /* Serial Mode Register */
+ scif_smr_write(0x00); /* 8bit,NonParity,Even,1Stop */
+
+ /* Bit Rate Register */
+ scif_brr_write(divrnd(sh_clock_get_pclock(), 32 * bps) - 1);
+
+ /*
+ * wait 2m Sec, because Send/Recv must begin 1 bit period after
+ * BRR is set.
+ */
+ delay(2000);
+
+#if 0
+ scif_fcr_write(FIFO_RCV_TRIGGER_14 | FIFO_XMT_TRIGGER_1 | SCFCR2_MCE);
+#else
+ scif_fcr_write(FIFO_RCV_TRIGGER_14 | FIFO_XMT_TRIGGER_1);
+#endif
+
+ /* Send permission, Receive permission ON */
+ scif_scr_write(SCSCR2_TE | SCSCR2_RE);
+
+ /* Serial Status Register */
+ scif_ssr_write(scif_ssr_read() & SCSSR2_TDFE); /* Clear Status */
+}
+
+
+/*
+ * scif_putc
+ * : unsigned char c;
+ */
+
+void
+scif_putc(unsigned char c)
+{
+ /* wait for ready */
+ while ((scif_fdr_read() & SCFDR2_TXCNT) == SCFDR2_TXF_FULL)
+ continue;
+
+ /* write send data to send register */
+ scif_ftdr_write(c);
+
+ /* clear ready flag */
+ scif_ssr_write(scif_ssr_read() & ~(SCSSR2_TDFE | SCSSR2_TEND));
+}
+
+/*
+ * : ScifErrCheck
+ * 0x80 = error
+ * 0x08 = frame error
+ * 0x04 = parity error
+ */
+int
+ScifErrCheck(void)
+{
+ return (scif_ssr_read() & (SCSSR2_ER | SCSSR2_FER | SCSSR2_PER));
+}
+
+/*
+ * scif_getc
+ */
+unsigned char
+scif_getc(void)
+{
+ unsigned char c, err_c;
+#ifdef SH4
+ unsigned short err_c2 = 0; /* XXXGCC: -Wuninitialized */
+#endif
+
+ for (;;) {
+ /* wait for ready */
+ while ((scif_fdr_read() & SCFDR2_RECVCNT) == 0)
+ continue;
+
+ c = scif_frdr_read();
+ err_c = scif_ssr_read();
+ scif_ssr_write(scif_ssr_read()
+ & ~(SCSSR2_ER | SCSSR2_BRK | SCSSR2_RDF | SCSSR2_DR));
+#ifdef SH4
+ if (CPU_IS_SH4) {
+ err_c2 = scif_lsr_read();
+ scif_lsr_write(scif_lsr_read() & ~SCLSR2_ORER);
+ }
+#endif
+ if ((err_c & (SCSSR2_ER | SCSSR2_BRK | SCSSR2_FER
+ | SCSSR2_PER)) == 0) {
+#ifdef SH4
+ if (CPU_IS_SH4 && ((err_c2 & SCLSR2_ORER) == 0))
+#endif
+ return(c);
+ }
+ }
+
+}
+
+int
+scif_match(struct device *parent, void *vcf, void *aux)
+{
+ if (scif_attached != 0)
+ return 0;
+
+ return 1;
+}
+
+void
+scif_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct scif_softc *sc = (struct scif_softc *)self;
+ struct tty *tp;
+
+ scif_attached = 1;
+
+ sc->sc_hwflags = 0; /* XXX */
+ sc->sc_swflags = 0; /* XXX */
+ sc->sc_fifolen = 16;
+
+ if (scifisconsole) {
+ /* InitializeScif(scifcn_speed); */
+ SET(sc->sc_hwflags, SCIF_HW_CONSOLE);
+ SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
+ printf("\n%s: console\n", sc->sc_dev.dv_xname);
+ } else {
+ InitializeScif(9600);
+ printf("\n");
+ }
+
+ timeout_set(&sc->sc_diag_tmo, scifdiag, sc);
+#ifdef SH4
+ intc_intr_establish(SH4_INTEVT_SCIF_ERI, IST_LEVEL, IPL_SERIAL,
+ scifintr, sc, self->dv_xname);
+ intc_intr_establish(SH4_INTEVT_SCIF_RXI, IST_LEVEL, IPL_SERIAL,
+ scifintr, sc, self->dv_xname);
+ intc_intr_establish(SH4_INTEVT_SCIF_BRI, IST_LEVEL, IPL_SERIAL,
+ scifintr, sc, self->dv_xname);
+ intc_intr_establish(SH4_INTEVT_SCIF_TXI, IST_LEVEL, IPL_SERIAL,
+ scifintr, sc, self->dv_xname);
+#else
+ intc_intr_establish(SH7709_INTEVT2_SCIF_ERI, IST_LEVEL, IPL_SERIAL,
+ scifintr, sc, self->dv_xname);
+ intc_intr_establish(SH7709_INTEVT2_SCIF_RXI, IST_LEVEL, IPL_SERIAL,
+ scifintr, sc, self->dv_xname);
+ intc_intr_establish(SH7709_INTEVT2_SCIF_BRI, IST_LEVEL, IPL_SERIAL,
+ scifintr, sc, self->dv_xname);
+ intc_intr_establish(SH7709_INTEVT2_SCIF_TXI, IST_LEVEL, IPL_SERIAL,
+ scifintr, sc, self->dv_xname);
+#endif
+
+ sc->sc_si = softintr_establish(IPL_SOFTSERIAL, scifsoft, sc);
+ SET(sc->sc_hwflags, SCIF_HW_DEV_OK);
+
+ tp = ttymalloc();
+ tp->t_oproc = scifstart;
+ tp->t_param = scifparam;
+ tp->t_hwiflow = NULL;
+
+ sc->sc_tty = tp;
+ sc->sc_rbuf = malloc(scif_rbuf_size << 1, M_DEVBUF, M_NOWAIT);
+ if (sc->sc_rbuf == NULL) {
+ printf("%s: unable to allocate ring buffer\n",
+ sc->sc_dev.dv_xname);
+ return;
+ }
+ sc->sc_ebuf = sc->sc_rbuf + (scif_rbuf_size << 1);
+}
+
+/*
+ * Start or restart transmission.
+ */
+void
+scifstart(struct tty *tp)
+{
+ struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(tp->t_dev)];
+ int s;
+
+ s = spltty();
+ if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
+ goto out;
+ if (sc->sc_tx_stopped)
+ goto out;
+
+ if (tp->t_outq.c_cc <= tp->t_lowat) {
+ if (ISSET(tp->t_state, TS_ASLEEP)) {
+ CLR(tp->t_state, TS_ASLEEP);
+ wakeup(&tp->t_outq);
+ }
+ selwakeup(&tp->t_wsel);
+ if (tp->t_outq.c_cc == 0)
+ goto out;
+ }
+
+ /* Grab the first contiguous region of buffer space. */
+ {
+ u_char *tba;
+ int tbc;
+
+ tba = tp->t_outq.c_cf;
+ tbc = ndqb(&tp->t_outq, 0);
+
+ (void)splserial();
+
+ sc->sc_tba = tba;
+ sc->sc_tbc = tbc;
+ }
+
+ SET(tp->t_state, TS_BUSY);
+ sc->sc_tx_busy = 1;
+
+ /* Enable transmit completion interrupts if necessary. */
+ scif_scr_write(scif_scr_read() | SCSCR2_TIE | SCSCR2_RIE);
+
+ /* Output the first chunk of the contiguous buffer. */
+ {
+ int n;
+ int maxchars;
+ int i;
+
+ n = sc->sc_tbc;
+ maxchars = sc->sc_fifolen
+ - ((scif_fdr_read() & SCFDR2_TXCNT) >> 8);
+ if (n > maxchars)
+ n = maxchars;
+
+ for (i = 0; i < n; i++) {
+ scif_putc(*(sc->sc_tba));
+ sc->sc_tba++;
+ }
+ sc->sc_tbc -= n;
+ }
+out:
+ splx(s);
+ return;
+}
+
+/*
+ * Set SCIF tty parameters from termios.
+ * XXX - Should just copy the whole termios after
+ * making sure all the changes could be done.
+ */
+int
+scifparam(struct tty *tp, struct termios *t)
+{
+ struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(tp->t_dev)];
+ int ospeed = t->c_ospeed;
+ int s;
+
+ /* Check requested parameters. */
+ if (ospeed < 0)
+ return (EINVAL);
+ if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
+ return (EINVAL);
+
+ /*
+ * For the console, always force CLOCAL and !HUPCL, so that the port
+ * is always active.
+ */
+ if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) ||
+ ISSET(sc->sc_hwflags, SCIF_HW_CONSOLE)) {
+ SET(t->c_cflag, CLOCAL);
+ CLR(t->c_cflag, HUPCL);
+ }
+
+ /*
+ * If there were no changes, don't do anything. This avoids dropping
+ * input and improves performance when all we did was frob things like
+ * VMIN and VTIME.
+ */
+ if (tp->t_ospeed == t->c_ospeed &&
+ tp->t_cflag == t->c_cflag)
+ return (0);
+
+#if 0
+/* XXX (msaitoh) */
+ lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag);
+#endif
+
+ s = splserial();
+
+ /*
+ * Set the flow control pins depending on the current flow control
+ * mode.
+ */
+ if (ISSET(t->c_cflag, CRTSCTS)) {
+ scif_fcr_write(scif_fcr_read() | SCFCR2_MCE);
+ } else {
+ scif_fcr_write(scif_fcr_read() & ~SCFCR2_MCE);
+ }
+
+ scif_brr_write(divrnd(sh_clock_get_pclock(), 32 * ospeed) -1);
+
+ /*
+ * Set the FIFO threshold based on the receive speed.
+ *
+ * * If it's a low speed, it's probably a mouse or some other
+ * interactive device, so set the threshold low.
+ * * If it's a high speed, trim the trigger level down to prevent
+ * overflows.
+ * * Otherwise set it a bit higher.
+ */
+#if 0
+/* XXX (msaitoh) */
+ if (ISSET(sc->sc_hwflags, SCIF_HW_HAYESP))
+ sc->sc_fifo = FIFO_DMA_MODE | FIFO_ENABLE | FIFO_TRIGGER_8;
+ else if (ISSET(sc->sc_hwflags, SCIF_HW_FIFO))
+ sc->sc_fifo = FIFO_ENABLE |
+ (t->c_ospeed <= 1200 ? FIFO_TRIGGER_1 :
+ t->c_ospeed <= 38400 ? FIFO_TRIGGER_8 : FIFO_TRIGGER_4);
+ else
+ sc->sc_fifo = 0;
+#endif
+
+ /* And copy to tty. */
+ tp->t_ispeed = 0;
+ tp->t_ospeed = t->c_ospeed;
+ tp->t_cflag = t->c_cflag;
+
+ if (!sc->sc_heldchange) {
+ if (sc->sc_tx_busy) {
+ sc->sc_heldtbc = sc->sc_tbc;
+ sc->sc_tbc = 0;
+ sc->sc_heldchange = 1;
+ }
+#if 0
+/* XXX (msaitoh) */
+ else
+ scif_loadchannelregs(sc);
+#endif
+ }
+
+ if (!ISSET(t->c_cflag, CHWFLOW)) {
+ /* Disable the high water mark. */
+ sc->sc_r_hiwat = 0;
+ sc->sc_r_lowat = 0;
+ if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
+ CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
+ scif_schedrx(sc);
+ }
+ } else {
+ sc->sc_r_hiwat = scif_rbuf_hiwat;
+ sc->sc_r_lowat = scif_rbuf_lowat;
+ }
+
+ splx(s);
+
+#ifdef SCIF_DEBUG
+ if (scif_debug)
+ scifstatus(sc, "scifparam ");
+#endif
+
+ if (!ISSET(t->c_cflag, CHWFLOW)) {
+ if (sc->sc_tx_stopped) {
+ sc->sc_tx_stopped = 0;
+ scifstart(tp);
+ }
+ }
+
+ return (0);
+}
+
+void
+scif_iflush(struct scif_softc *sc)
+{
+ int i;
+ unsigned char c;
+
+ i = scif_fdr_read() & SCFDR2_RECVCNT;
+
+ while (i > 0) {
+ c = scif_frdr_read();
+ scif_ssr_write(scif_ssr_read() & ~(SCSSR2_RDF | SCSSR2_DR));
+ i--;
+ }
+}
+
+int
+scifopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ int unit = SCIFUNIT(dev);
+ struct scif_softc *sc;
+ struct tty *tp;
+ int s, s2;
+ int error;
+
+ if (unit >= scif_cd.cd_ndevs)
+ return (ENXIO);
+ sc = scif_cd.cd_devs[unit];
+ if (sc == 0 || !ISSET(sc->sc_hwflags, SCIF_HW_DEV_OK) ||
+ sc->sc_rbuf == NULL)
+ return (ENXIO);
+
+ tp = sc->sc_tty;
+
+ if (ISSET(tp->t_state, TS_ISOPEN) &&
+ ISSET(tp->t_state, TS_XCLUDE) &&
+ p->p_ucred->cr_uid != 0)
+ return (EBUSY);
+
+ s = spltty();
+
+ /*
+ * Do the following iff this is a first open.
+ */
+ if (!ISSET(tp->t_state, TS_ISOPEN)) {
+ struct termios t;
+
+ tp->t_dev = dev;
+
+ s2 = splserial();
+
+ /* Turn on interrupts. */
+ scif_scr_write(scif_scr_read() | SCSCR2_TIE | SCSCR2_RIE);
+
+ splx(s2);
+
+ /*
+ * Initialize the termios status to the defaults. Add in the
+ * sticky bits from TIOCSFLAGS.
+ */
+ t.c_ispeed = 0;
+ if (ISSET(sc->sc_hwflags, SCIF_HW_CONSOLE)) {
+ t.c_ospeed = scifcn_speed; /* XXX (msaitoh) */
+ t.c_cflag = scifconscflag;
+ } else {
+ t.c_ospeed = TTYDEF_SPEED;
+ t.c_cflag = TTYDEF_CFLAG;
+ }
+ if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
+ SET(t.c_cflag, CLOCAL);
+ if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
+ SET(t.c_cflag, CRTSCTS);
+ if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
+ SET(t.c_cflag, MDMBUF);
+ /* Make sure scifparam() will do something. */
+ tp->t_ospeed = 0;
+ (void) scifparam(tp, &t);
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_lflag = TTYDEF_LFLAG;
+ ttychars(tp);
+ ttsetwater(tp);
+
+ s2 = splserial();
+
+ /* Clear the input ring, and unblock. */
+ sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
+ sc->sc_rbavail = scif_rbuf_size;
+ scif_iflush(sc);
+ CLR(sc->sc_rx_flags, RX_ANY_BLOCK);
+#if 0
+/* XXX (msaitoh) */
+ scif_hwiflow(sc);
+#endif
+
+#ifdef SCIF_DEBUG
+ if (scif_debug)
+ scifstatus(sc, "scifopen ");
+#endif
+
+ splx(s2);
+ }
+
+ splx(s);
+
+ error = ttyopen(dev, tp);
+ if (error)
+ goto bad;
+
+ error = (*linesw[tp->t_line].l_open)(dev, tp);
+ if (error)
+ goto bad;
+
+ return (0);
+
+bad:
+
+ return (error);
+}
+
+int
+scifclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)];
+ struct tty *tp = sc->sc_tty;
+
+ /* XXX This is for cons.c. */
+ if (!ISSET(tp->t_state, TS_ISOPEN))
+ return (0);
+
+ (*linesw[tp->t_line].l_close)(tp, flag);
+ ttyclose(tp);
+
+ return (0);
+}
+
+int
+scifread(dev_t dev, struct uio *uio, int flag)
+{
+ struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)];
+ struct tty *tp = sc->sc_tty;
+
+ return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+
+int
+scifwrite(dev_t dev, struct uio *uio, int flag)
+{
+ struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)];
+ struct tty *tp = sc->sc_tty;
+
+ return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+}
+
+#if 0
+int
+scifpoll(dev_t dev, int events, struct proc *p)
+{
+ struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)];
+ struct tty *tp = sc->sc_tty;
+
+ return ((*linesw[tp->t_line].l_poll)(tp, events, p));
+}
+#endif
+
+struct tty *
+sciftty(dev_t dev)
+{
+ struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)];
+ struct tty *tp = sc->sc_tty;
+
+ return (tp);
+}
+
+int
+scifioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)];
+ struct tty *tp = sc->sc_tty;
+ int error;
+ int s;
+
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error != -1)
+ return (error);
+
+ error = ttioctl(tp, cmd, data, flag, p);
+ if (error != -1)
+ return (error);
+
+ error = 0;
+
+ s = splserial();
+
+ switch (cmd) {
+ case TIOCSBRK:
+ scif_break(sc, 1);
+ break;
+
+ case TIOCCBRK:
+ scif_break(sc, 0);
+ break;
+
+ case TIOCGFLAGS:
+ *(int *)data = sc->sc_swflags;
+ break;
+
+ case TIOCSFLAGS:
+ error = suser(p, 0);
+ if (error)
+ break;
+ sc->sc_swflags = *(int *)data;
+ break;
+
+ default:
+ error = -1;
+ break;
+ }
+
+ splx(s);
+
+ return (error);
+}
+
+void
+scif_schedrx(struct scif_softc *sc)
+{
+ sc->sc_rx_ready = 1;
+
+ /* Wake up the poller. */
+ softintr_schedule(sc->sc_si);
+}
+
+void
+scif_break(struct scif_softc *sc, int onoff)
+{
+ if (onoff)
+ scif_ssr_write(scif_ssr_read() & ~SCSSR2_TDFE);
+ else
+ scif_ssr_write(scif_ssr_read() | SCSSR2_TDFE);
+
+#if 0 /* XXX */
+ if (!sc->sc_heldchange) {
+ if (sc->sc_tx_busy) {
+ sc->sc_heldtbc = sc->sc_tbc;
+ sc->sc_tbc = 0;
+ sc->sc_heldchange = 1;
+ } else
+ scif_loadchannelregs(sc);
+ }
+#endif
+}
+
+/*
+ * Stop output, e.g., for ^S or output flush.
+ */
+int
+scifstop(struct tty *tp, int flag)
+{
+ struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(tp->t_dev)];
+ int s;
+
+ s = splserial();
+ if (ISSET(tp->t_state, TS_BUSY)) {
+ /* Stop transmitting at the next chunk. */
+ sc->sc_tbc = 0;
+ sc->sc_heldtbc = 0;
+ if (!ISSET(tp->t_state, TS_TTSTOP))
+ SET(tp->t_state, TS_FLUSH);
+ }
+ splx(s);
+ return (0);
+}
+
+void
+scif_intr_init()
+{
+ /* XXX */
+}
+
+void
+scifdiag(void *arg)
+{
+ struct scif_softc *sc = arg;
+ int overflows, floods;
+ int s;
+
+ s = splserial();
+ overflows = sc->sc_overflows;
+ sc->sc_overflows = 0;
+ floods = sc->sc_floods;
+ sc->sc_floods = 0;
+ sc->sc_errors = 0;
+ splx(s);
+
+ log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
+ sc->sc_dev.dv_xname,
+ overflows, overflows == 1 ? "" : "s",
+ floods, floods == 1 ? "" : "s");
+}
+
+void
+scif_rxsoft(struct scif_softc *sc, struct tty *tp)
+{
+ int (*rint)(int, struct tty *) = *linesw[tp->t_line].l_rint;
+ u_char *get, *end;
+ u_int cc, scc;
+ u_char ssr2;
+ int code;
+ int s;
+
+ end = sc->sc_ebuf;
+ get = sc->sc_rbget;
+ scc = cc = scif_rbuf_size - sc->sc_rbavail;
+
+ if (cc == scif_rbuf_size) {
+ sc->sc_floods++;
+ if (sc->sc_errors++ == 0)
+ timeout_add(&sc->sc_diag_tmo, 60 * hz);
+ }
+
+ while (cc) {
+ code = get[0];
+ ssr2 = get[1];
+ if (ISSET(ssr2, SCSSR2_BRK | SCSSR2_FER | SCSSR2_PER)) {
+ if (ISSET(ssr2, SCSSR2_BRK | SCSSR2_FER))
+ SET(code, TTY_FE);
+ if (ISSET(ssr2, SCSSR2_PER))
+ SET(code, TTY_PE);
+ }
+ if ((*rint)(code, tp) == -1) {
+ /*
+ * The line discipline's buffer is out of space.
+ */
+ if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
+ /*
+ * We're either not using flow control, or the
+ * line discipline didn't tell us to block for
+ * some reason. Either way, we have no way to
+ * know when there's more space available, so
+ * just drop the rest of the data.
+ */
+ get += cc << 1;
+ if (get >= end)
+ get -= scif_rbuf_size << 1;
+ cc = 0;
+ } else {
+ /*
+ * Don't schedule any more receive processing
+ * until the line discipline tells us there's
+ * space available (through scifhwiflow()).
+ * Leave the rest of the data in the input
+ * buffer.
+ */
+ SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
+ }
+ break;
+ }
+ get += 2;
+ if (get >= end)
+ get = sc->sc_rbuf;
+ cc--;
+ }
+
+ if (cc != scc) {
+ sc->sc_rbget = get;
+ s = splserial();
+ cc = sc->sc_rbavail += scc - cc;
+ /* Buffers should be ok again, release possible block. */
+ if (cc >= sc->sc_r_lowat) {
+ if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
+ CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
+ scif_scr_write(scif_scr_read() | SCSCR2_RIE);
+ }
+#if 0
+ if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
+ CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
+ scif_hwiflow(sc);
+ }
+#endif
+ }
+ splx(s);
+ }
+}
+
+void
+scif_txsoft(struct scif_softc *sc, struct tty *tp)
+{
+ CLR(tp->t_state, TS_BUSY);
+ if (ISSET(tp->t_state, TS_FLUSH))
+ CLR(tp->t_state, TS_FLUSH);
+ else
+ ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
+ (*linesw[tp->t_line].l_start)(tp);
+}
+
+void
+scif_stsoft(struct scif_softc *sc, struct tty *tp)
+{
+#if 0
+/* XXX (msaitoh) */
+ u_char msr, delta;
+ int s;
+
+ s = splserial();
+ msr = sc->sc_msr;
+ delta = sc->sc_msr_delta;
+ sc->sc_msr_delta = 0;
+ splx(s);
+
+ if (ISSET(delta, sc->sc_msr_dcd)) {
+ /*
+ * Inform the tty layer that carrier detect changed.
+ */
+ (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD));
+ }
+
+ if (ISSET(delta, sc->sc_msr_cts)) {
+ /* Block or unblock output according to flow control. */
+ if (ISSET(msr, sc->sc_msr_cts)) {
+ sc->sc_tx_stopped = 0;
+ (*linesw[tp->t_line].l_start)(tp);
+ } else {
+ sc->sc_tx_stopped = 1;
+ }
+ }
+
+#ifdef SCIF_DEBUG
+ if (scif_debug)
+ scifstatus(sc, "scif_stsoft");
+#endif
+#endif
+}
+
+void
+scifsoft(void *arg)
+{
+ struct scif_softc *sc = arg;
+ struct tty *tp;
+
+ tp = sc->sc_tty;
+
+ if (sc->sc_rx_ready) {
+ sc->sc_rx_ready = 0;
+ scif_rxsoft(sc, tp);
+ }
+
+#if 0
+ if (sc->sc_st_check) {
+ sc->sc_st_check = 0;
+ scif_stsoft(sc, tp);
+ }
+#endif
+
+ if (sc->sc_tx_done) {
+ sc->sc_tx_done = 0;
+ scif_txsoft(sc, tp);
+ }
+}
+
+int
+scifintr(void *arg)
+{
+ struct scif_softc *sc = arg;
+ u_char *put, *end;
+ u_int cc;
+ u_short ssr2;
+ int count;
+
+ end = sc->sc_ebuf;
+ put = sc->sc_rbput;
+ cc = sc->sc_rbavail;
+
+ do {
+ ssr2 = scif_ssr_read();
+ if (ISSET(ssr2, SCSSR2_BRK)) {
+ scif_ssr_write(scif_ssr_read()
+ & ~(SCSSR2_ER | SCSSR2_BRK | SCSSR2_DR));
+#ifdef DDB
+ if (ISSET(sc->sc_hwflags, SCIF_HW_CONSOLE) &&
+ db_console != 0) {
+ Debugger();
+ }
+#endif /* DDB */
+ }
+ count = scif_fdr_read() & SCFDR2_RECVCNT;
+ if (count != 0) {
+ for (;;) {
+ u_char c = scif_frdr_read();
+ u_char err = (u_char)(scif_ssr_read() & 0x00ff);
+
+ scif_ssr_write(scif_ssr_read()
+ & ~(SCSSR2_ER | SCSSR2_RDF | SCSSR2_DR));
+#ifdef SH4
+ if (CPU_IS_SH4)
+ scif_lsr_write(scif_lsr_read()
+ & ~SCLSR2_ORER);
+#endif
+ if ((cc > 0) && (count > 0)) {
+ put[0] = c;
+ put[1] = err;
+ put += 2;
+ if (put >= end)
+ put = sc->sc_rbuf;
+ cc--;
+ count--;
+ } else
+ break;
+ }
+
+ /*
+ * Current string of incoming characters ended because
+ * no more data was available or we ran out of space.
+ * Schedule a receive event if any data was received.
+ * If we're out of space, turn off receive interrupts.
+ */
+ sc->sc_rbput = put;
+ sc->sc_rbavail = cc;
+ if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
+ sc->sc_rx_ready = 1;
+
+ /*
+ * See if we are in danger of overflowing a buffer. If
+ * so, use hardware flow control to ease the pressure.
+ */
+ if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) &&
+ cc < sc->sc_r_hiwat) {
+ SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
+#if 0
+ scif_hwiflow(sc);
+#endif
+ }
+
+ /*
+ * If we're out of space, disable receive interrupts
+ * until the queue has drained a bit.
+ */
+ if (!cc) {
+ SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
+ scif_scr_write(scif_scr_read() & ~SCSCR2_RIE);
+ }
+ } else {
+ if (scif_ssr_read() & (SCSSR2_RDF | SCSSR2_DR)) {
+ scif_scr_write(scif_scr_read()
+ & ~(SCSCR2_TIE | SCSCR2_RIE));
+ delay(10);
+ scif_scr_write(scif_scr_read()
+ | SCSCR2_TIE | SCSCR2_RIE);
+ continue;
+ }
+ }
+ } while (scif_ssr_read() & (SCSSR2_RDF | SCSSR2_DR));
+
+#if 0
+ msr = bus_space_read_1(iot, ioh, scif_msr);
+ delta = msr ^ sc->sc_msr;
+ sc->sc_msr = msr;
+ if (ISSET(delta, sc->sc_msr_mask)) {
+ SET(sc->sc_msr_delta, delta);
+
+ /*
+ * Pulse-per-second clock signal on edge of DCD?
+ */
+ if (ISSET(delta, sc->sc_ppsmask)) {
+ struct timeval tv;
+ if (ISSET(msr, sc->sc_ppsmask) ==
+ sc->sc_ppsassert) {
+ /* XXX nanotime() */
+ microtime(&tv);
+ TIMEVAL_TO_TIMESPEC(&tv,
+ &sc->ppsinfo.assert_timestamp);
+ if (sc->ppsparam.mode & PPS_OFFSETASSERT) {
+ timespecadd(&sc->ppsinfo.assert_timestamp,
+ &sc->ppsparam.assert_offset,
+ &sc->ppsinfo.assert_timestamp);
+ TIMESPEC_TO_TIMEVAL(&tv, &sc->ppsinfo.assert_timestamp);
+ }
+
+#ifdef PPS_SYNC
+ if (sc->ppsparam.mode & PPS_HARDPPSONASSERT)
+ hardpps(&tv, tv.tv_usec);
+#endif
+ sc->ppsinfo.assert_sequence++;
+ sc->ppsinfo.current_mode =
+ sc->ppsparam.mode;
+
+ } else if (ISSET(msr, sc->sc_ppsmask) ==
+ sc->sc_ppsclear) {
+ /* XXX nanotime() */
+ microtime(&tv);
+ TIMEVAL_TO_TIMESPEC(&tv,
+ &sc->ppsinfo.clear_timestamp);
+ if (sc->ppsparam.mode & PPS_OFFSETCLEAR) {
+ timespecadd(&sc->ppsinfo.clear_timestamp,
+ &sc->ppsparam.clear_offset,
+ &sc->ppsinfo.clear_timestamp);
+ TIMESPEC_TO_TIMEVAL(&tv, &sc->ppsinfo.clear_timestamp);
+ }
+
+#ifdef PPS_SYNC
+ if (sc->ppsparam.mode & PPS_HARDPPSONCLEAR)
+ hardpps(&tv, tv.tv_usec);
+#endif
+ sc->ppsinfo.clear_sequence++;
+ sc->ppsinfo.current_mode =
+ sc->ppsparam.mode;
+ }
+ }
+
+ /*
+ * Stop output immediately if we lose the output
+ * flow control signal or carrier detect.
+ */
+ if (ISSET(~msr, sc->sc_msr_mask)) {
+ sc->sc_tbc = 0;
+ sc->sc_heldtbc = 0;
+#ifdef SCIF_DEBUG
+ if (scif_debug)
+ scifstatus(sc, "scifintr ");
+#endif
+ }
+
+ sc->sc_st_check = 1;
+ }
+#endif
+
+ /*
+ * Done handling any receive interrupts. See if data can be
+ * transmitted as well. Schedule tx done event if no data left
+ * and tty was marked busy.
+ */
+ if (((scif_fdr_read() & SCFDR2_TXCNT) >> 8) != 16) { /* XXX (msaitoh) */
+ /*
+ * If we've delayed a parameter change, do it now, and restart
+ * output.
+ */
+ if (sc->sc_heldchange) {
+ sc->sc_heldchange = 0;
+ sc->sc_tbc = sc->sc_heldtbc;
+ sc->sc_heldtbc = 0;
+ }
+
+ /* Output the next chunk of the contiguous buffer, if any. */
+ if (sc->sc_tbc > 0) {
+ int n;
+ int maxchars;
+ int i;
+
+ n = sc->sc_tbc;
+ maxchars = sc->sc_fifolen -
+ ((scif_fdr_read() & SCFDR2_TXCNT) >> 8);
+ if (n > maxchars)
+ n = maxchars;
+
+ for (i = 0; i < n; i++) {
+ scif_putc(*(sc->sc_tba));
+ sc->sc_tba++;
+ }
+ sc->sc_tbc -= n;
+ } else {
+ /* Disable transmit completion interrupts if necessary. */
+#if 0
+ if (ISSET(sc->sc_ier, IER_ETXRDY))
+#endif
+ scif_scr_write(scif_scr_read() & ~SCSCR2_TIE);
+
+ if (sc->sc_tx_busy) {
+ sc->sc_tx_busy = 0;
+ sc->sc_tx_done = 1;
+ }
+ }
+ }
+
+ /* Wake up the poller. */
+ softintr_schedule(sc->sc_si);
+
+ return (1);
+}
+
+void
+scifcnprobe(struct consdev *cp)
+{
+ int maj;
+
+ /* locate the major number */
+ for (maj = 0; maj < nchrdev; maj++)
+ if (cdevsw[maj].d_open == scifopen)
+ break;
+
+ cp->cn_dev = makedev(maj, 0);
+#ifdef SCIFCONSOLE
+ cp->cn_pri = CN_REMOTE;
+#else
+ cp->cn_pri = CN_NORMAL;
+#endif
+}
+
+void
+scifcninit(struct consdev *cp)
+{
+ InitializeScif(scifcn_speed);
+ scifisconsole = 1;
+}
+
+int
+scifcngetc(dev_t dev)
+{
+ int c;
+ int s;
+
+ s = splserial();
+ c = scif_getc();
+ splx(s);
+
+ return (c);
+}
+
+void
+scifcnputc(dev_t dev, int c)
+{
+ int s;
+
+ s = splserial();
+ scif_putc((u_char)c);
+ splx(s);
+}
diff --git a/sys/arch/sh/dev/scifreg.h b/sys/arch/sh/dev/scifreg.h
new file mode 100644
index 00000000000..3baf31f7f90
--- /dev/null
+++ b/sys/arch/sh/dev/scifreg.h
@@ -0,0 +1,164 @@
+/* $OpenBSD: scifreg.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: scifreg.h,v 1.10 2006/02/18 00:41:32 uwe Exp $ */
+
+/*-
+ * Copyright (C) 1999 SAITOH Masanobu. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Serial Communication Interface with FIFO (SCIF)
+ */
+
+#define SH3_SCIF0_BASE 0xa4000150
+#define SH3_SCIF1_BASE 0xa4000140
+
+#define SH4_SCIF_BASE 0xffe80000
+
+#ifdef SH3
+
+/* SH3 definitions */
+
+#define SCIF_SMR 0x0 /* serial mode */
+#define SCIF_BRR 0x2 /* bit rate */
+#define SCIF_SCR 0x4 /* serial control */
+#define SCIF_FTDR 0x6 /* transmit fifo data */
+#define SCIF_SSR 0x8 /* serial status */
+#define SCIF_FRDR 0xa /* receive fifo data */
+#define SCIF_FCR 0xc /* fifo control */
+#define SCIF_FDR 0xe /* fifo data count set */
+
+#define SHREG_SCSMR2 (*(volatile uint8_t *)(SH3_SCIF0_BASE + SCIF_SMR))
+#define SHREG_SCBRR2 (*(volatile uint8_t *)(SH3_SCIF0_BASE + SCIF_BRR))
+#define SHREG_SCSCR2 (*(volatile uint8_t *)(SH3_SCIF0_BASE + SCIF_SCR))
+#define SHREG_SCFTDR2 (*(volatile uint8_t *)(SH3_SCIF0_BASE + SCIF_FTDR))
+#define SHREG_SCSSR2 (*(volatile uint16_t *)(SH3_SCIF0_BASE + SCIF_SSR))
+#define SHREG_SCFRDR2 (*(volatile uint8_t *)(SH3_SCIF0_BASE + SCIF_FRDR))
+#define SHREG_SCFCR2 (*(volatile uint8_t *)(SH3_SCIF0_BASE + SCIF_FCR))
+#define SHREG_SCFDR2 (*(volatile uint16_t *)(SH3_SCIF0_BASE + SCIF_FDR))
+
+#else /* !SH3 */
+
+/* SH4 definitions */
+
+#define SCIF_SMR 0x00 /* serial mode */
+#define SCIF_BRR 0x04 /* bit rate */
+#define SCIF_SCR 0x08 /* serial control */
+#define SCIF_FTDR 0x0c /* transmit fifo data */
+#define SCIF_SSR 0x10 /* serial status */
+#define SCIF_FRDR 0x14 /* receive fifo data */
+#define SCIF_FCR 0x18 /* fifo control */
+#define SCIF_FDR 0x1c /* fifo data count set */
+
+#define SCIF_SPTR 0x20 /* seial port */
+#define SCIF_LSR 0x24 /* line status */
+
+#define SHREG_SCSMR2 (*(volatile uint16_t *)(SH4_SCIF_BASE + SCIF_SMR))
+#define SHREG_SCBRR2 (*(volatile uint8_t *)(SH4_SCIF_BASE + SCIF_BRR))
+#define SHREG_SCSCR2 (*(volatile uint16_t *)(SH4_SCIF_BASE + SCIF_SCR))
+#define SHREG_SCFTDR2 (*(volatile uint8_t *)(SH4_SCIF_BASE + SCIF_FTDR))
+#define SHREG_SCSSR2 (*(volatile uint16_t *)(SH4_SCIF_BASE + SCIF_SSR))
+#define SHREG_SCFRDR2 (*(volatile uint8_t *)(SH4_SCIF_BASE + SCIF_FRDR))
+#define SHREG_SCFCR2 (*(volatile uint16_t *)(SH4_SCIF_BASE + SCIF_FCR))
+#define SHREG_SCFDR2 (*(volatile uint16_t *)(SH4_SCIF_BASE + SCIF_FDR))
+
+#define SHREG_SCSPTR2 (*(volatile uint16_t *)(SH4_SCIF_BASE + SCIF_SPTR))
+#define SHREG_SCLSR2 (*(volatile uint16_t *)(SH4_SCIF_BASE + SCIF_LSR))
+
+/* alias */
+#define SHREG_SCSFDR2 SHREG_SCFTDR2
+#define SHREG_SCFSR2 SHREG_SCSSR2
+
+#define SCSPTR2_RTSIO 0x0080
+#define SCSPTR2_RTSDT 0x0040
+#define SCSPTR2_CTSIO 0x0020
+#define SCSPTR2_CTSDT 0x0010
+#define SCSPTR2_SCKIO 0x0008
+#define SCSPTR2_SCKDT 0x0004
+#define SCSPTR2_SPB2IO 0x0002
+#define SCSPTR2_SPB2DT 0x0001
+
+#define SCLSR2_ORER 0x0001 /* overrun error */
+
+#endif /* !SH3 */
+
+/* SMR: serial mode */
+#define SCSMR2_CHR 0x40 /* character width (set = 7bit) */
+#define SCSMR2_PE 0x20 /* Parity Enable */
+#define SCSMR2_O 0x10 /* parity mode Odd */
+#define SCSMR2_STOP 0x08 /* STOP bit (set = 2 stop bits) */
+#define SCSMR2_CKS1 0x02 /* ClocK Select 1 */
+#define SCSMR2_CKS0 0x01 /* ClocK Select 0 */
+
+/* SMR: serial mode (for IrDA) */
+#define SCSMR2_IRMOD 0x80 /* IrDA mode */
+#define SCSMR2_ICK3 0x40
+#define SCSMR2_ICK2 0x20
+#define SCSMR2_ICK1 0x10
+#define SCSMR2_ICK0 0x08
+#define SCSMR2_PSEL 0x04 /* Pulse width SELelect */
+
+/* SCR: serial control */
+#define SCSCR2_TIE 0x80 /* Transmit Interrupt Enable */
+#define SCSCR2_RIE 0x40 /* Recieve Interrupt Enable */
+#define SCSCR2_TE 0x20 /* Transmit Enable */
+#define SCSCR2_RE 0x10 /* Receive Enable */
+#define SCSCR2_CKE1 0x02 /* ClocK Enable 1 */
+#define SCSCR2_CKE0 0x01 /* ClocK Enable 0 (not in sh4) */
+
+/* SSR: serial status */
+#define SCSSR2_ER 0x0080 /* ERror */
+#define SCSSR2_TEND 0x0040 /* Transmit END */
+#define SCSSR2_TDFE 0x0020 /* Transmit Data Fifo Empty */
+#define SCSSR2_BRK 0x0010 /* BReaK detection */
+#define SCSSR2_FER 0x0008 /* Framing ERror */
+#define SCSSR2_PER 0x0004 /* Parity ERror */
+#define SCSSR2_RDF 0x0002 /* Recieve fifo Data Full */
+#define SCSSR2_DR 0x0001 /* Data Ready */
+
+/* FCR: fifo control */
+#define SCFCR2_RTRG1 0x80 /* Receive TRiGger 1 */
+#define SCFCR2_RTRG0 0x40 /* Receive TRiGger 0 */
+#define SCFCR2_TTRG1 0x20 /* Transmit TRiGger 1 */
+#define SCFCR2_TTRG0 0x10 /* Transmit TRiGger 0 */
+#define SCFCR2_MCE 0x08 /* Modem Control Enable */
+#define SCFCR2_TFRST 0x04 /* Transmit Fifo register ReSeT */
+#define SCFCR2_RFRST 0x02 /* Receive Fifo register ReSeT */
+#define SCFCR2_LOOP 0x01 /* LOOP back test */
+
+#define FIFO_RCV_TRIGGER_1 0x00
+#define FIFO_RCV_TRIGGER_4 0x40
+#define FIFO_RCV_TRIGGER_8 0x80
+#define FIFO_RCV_TRIGGER_14 0xc0
+
+#define FIFO_XMT_TRIGGER_8 0x00
+#define FIFO_XMT_TRIGGER_4 0x10
+#define FIFO_XMT_TRIGGER_2 0x20
+#define FIFO_XMT_TRIGGER_1 0x30
+
+/* FDR: fifo data count set */
+#define SCFDR2_TXCNT 0xff00 /* Tx CouNT */
+#define SCFDR2_RECVCNT 0x00ff /* Rx CouNT */
+#define SCFDR2_TXF_FULL 0x1000 /* Tx FULL */
+#define SCFDR2_RXF_EPTY 0x0000 /* Rx EMPTY */
diff --git a/sys/arch/sh/dev/scireg.h b/sys/arch/sh/dev/scireg.h
new file mode 100644
index 00000000000..bd3d2529c4e
--- /dev/null
+++ b/sys/arch/sh/dev/scireg.h
@@ -0,0 +1,82 @@
+/* $OpenBSD: scireg.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: scireg.h,v 1.8 2003/07/01 11:49:37 uwe Exp $ */
+
+/*-
+ * Copyright (C) 1999 SAITOH Masanobu. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Serial Communication Interface (SCI)
+ */
+
+#if !defined(SH4)
+
+/* SH3 definitions */
+
+#define SHREG_SCSMR (*(volatile unsigned char *) 0xFFFFFE80)
+#define SHREG_SCBRR (*(volatile unsigned char *) 0xFFFFFE82)
+#define SHREG_SCSCR (*(volatile unsigned char *) 0xFFFFFE84)
+#define SHREG_SCTDR (*(volatile unsigned char *) 0xFFFFFE86)
+#define SHREG_SCSSR (*(volatile unsigned char *) 0xFFFFFE88)
+#define SHREG_SCRDR (*(volatile unsigned char *) 0xFFFFFE8A)
+#define SHREG_SCSPDR (*(volatile unsigned char *) 0xf4000136)
+
+#else
+
+/* SH4 definitions */
+
+#define SHREG_SCSMR (*(volatile unsigned char *) 0xffe00000)
+#define SHREG_SCBRR (*(volatile unsigned char *) 0xffe00004)
+#define SHREG_SCSCR (*(volatile unsigned char *) 0xffe00008)
+#define SHREG_SCTDR (*(volatile unsigned char *) 0xffe0000c)
+#define SHREG_SCSSR (*(volatile unsigned char *) 0xffe00010)
+#define SHREG_SCRDR (*(volatile unsigned char *) 0xffe00014)
+#define SHREG_SCSPTR (*(volatile unsigned char *) 0xffe0001c)
+
+#endif
+
+#define SCSCR_TIE 0x80 /* Transmit Interrupt Enable */
+#define SCSCR_RIE 0x40 /* Receive Interrupt Enable */
+#define SCSCR_TE 0x20 /* Transmit Enable */
+#define SCSCR_RE 0x10 /* Receive Enable */
+#define SCSCR_MPIE 0x08 /* Multi Processor Interrupt Enable */
+#define SCSCR_TEIE 0x04 /* Transmit End Interrupt Enable */
+#define SCSCR_CKE1 0x02 /* ClocK Enable 1 */
+#define SCSCR_CKE0 0x01 /* ClocK Enable 0 */
+
+#define SCSSR_TDRE 0x80
+#define SCSSR_RDRF 0x40
+#define SCSSR_ORER 0x20
+#define SCSSR_FER 0x10
+#define SCSSR_PER 0x08
+
+#define SCSPTR_SPB1IO 0x08
+#define SCSPTR_SPB1DT 0x04
+#define SCSPTR_SPB0IO 0x02
+#define SCSPTR_SPB0DT 0x01
+
+#if defined(SH3)
+#define SCSPDR_SCP0DT 0x01
+#endif
diff --git a/sys/arch/sh/dev/shb.c b/sys/arch/sh/dev/shb.c
new file mode 100644
index 00000000000..2880a647b0b
--- /dev/null
+++ b/sys/arch/sh/dev/shb.c
@@ -0,0 +1,91 @@
+/* $OpenBSD: shb.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: shb.c,v 1.10 2005/12/11 12:18:58 christos Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/autoconf.h>
+
+int shb_match(struct device *, void *, void *);
+void shb_attach(struct device *, struct device *, void *);
+int shb_print(void *, const char *);
+int shb_search(struct device *, void *, void *);
+
+struct cfattach shb_ca = {
+ sizeof(struct device), shb_match, shb_attach
+};
+
+struct cfdriver shb_cd = {
+ 0, "shb", DV_DULL
+};
+
+int
+shb_match(struct device *parent, void *vcf, void *aux)
+{
+ extern struct cfdriver shb_cd;
+ struct mainbus_attach_args *ma = aux;
+
+ if (strcmp(ma->ma_name, shb_cd.cd_name) != 0)
+ return (0);
+
+ return (1);
+}
+
+void
+shb_attach(struct device *parent, struct device *self, void *aux)
+{
+ printf("\n");
+
+ config_search(shb_search, self, aux);
+}
+
+int
+shb_search(struct device *parent, void *vcf, void *aux)
+{
+ struct cfdata *cf = vcf;
+
+ if ((*cf->cf_attach->ca_match)(parent, cf, NULL) == 0)
+ return (0);
+ config_attach(parent, cf, NULL, shb_print);
+ return (1);
+}
+
+int
+shb_print(void *aux, const char *pnp)
+{
+ return (UNCONF);
+}
diff --git a/sys/arch/sh/dev/shpcic.c b/sys/arch/sh/dev/shpcic.c
new file mode 100644
index 00000000000..c1357e2d708
--- /dev/null
+++ b/sys/arch/sh/dev/shpcic.c
@@ -0,0 +1,1182 @@
+/* $OpenBSD: shpcic.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: shpcic.c,v 1.10 2005/12/24 20:07:32 perry Exp $ */
+
+/*
+ * Copyright (c) 2005 NONAKA Kimihiro
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/extent.h>
+#include <sys/malloc.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <sh/bscreg.h>
+#include <sh/cache.h>
+#include <sh/trap.h>
+#include <sh/dev/pcicreg.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#if defined(SHPCIC_DEBUG)
+int shpcic_debug = 0;
+#define DPRINTF(arg) if (shpcic_debug) printf arg
+#else
+#define DPRINTF(arg)
+#endif
+
+#define PCI_MODE1_ENABLE 0x80000000UL
+
+static const struct shpcic_product {
+ uint32_t sp_product;
+ const char *sp_name;
+} shpcic_products[] = {
+ { PCI_PRODUCT_HITACHI_SH7751, "SH7751" },
+ { PCI_PRODUCT_HITACHI_SH7751R, "SH7751R" },
+
+ { 0, NULL },
+};
+
+int shpcic_match(struct device *, void *, void *);
+void shpcic_attach(struct device *, struct device *, void *);
+
+struct cfattach shpcic_ca = {
+ sizeof(struct device), shpcic_match, shpcic_attach
+};
+
+struct cfdriver shpcic_cd = {
+ 0, "shpcic", DV_DULL
+};
+
+/* There can be only one. */
+int shpcic_found = 0;
+
+/* PCIC intr priotiry */
+static int shpcic_intr_priority[2] = { IPL_BIO, IPL_BIO };
+
+static const struct shpcic_product *shpcic_lookup(void);
+
+static const struct shpcic_product *
+shpcic_lookup(void)
+{
+ const struct shpcic_product *spp;
+ pcireg_t id;
+
+ id = _reg_read_4(SH4_PCICONF0);
+ switch (PCI_VENDOR(id)) {
+ case PCI_VENDOR_HITACHI:
+ break;
+
+ default:
+ return (NULL);
+ }
+
+ for (spp = shpcic_products; spp->sp_name != NULL; spp++) {
+ if (PCI_PRODUCT(id) == spp->sp_product) {
+ return (spp);
+ }
+ }
+ return (NULL);
+}
+
+int
+shpcic_match(struct device *parent, void *vcf, void *aux)
+{
+ if (!CPU_IS_SH4)
+ return (0);
+
+ switch (cpu_product) {
+ default:
+ return (0);
+
+ case CPU_PRODUCT_7751:
+ case CPU_PRODUCT_7751R:
+ break;
+ }
+
+ if (shpcic_found)
+ return (0);
+
+ if (shpcic_lookup() == NULL)
+ return (0);
+
+ if (_reg_read_2(SH4_BCR2) & BCR2_PORTEN)
+ return (0);
+
+ return (1);
+}
+
+void
+shpcic_attach(struct device *parent, struct device *self, void *aux)
+{
+ const struct shpcic_product *spp;
+ struct pcibus_attach_args pba;
+
+ shpcic_found = 1;
+
+ spp = shpcic_lookup();
+ if (spp == NULL) {
+ printf("\n");
+ panic("shpcic_attach: impossible");
+ }
+
+ if (_reg_read_2(SH4_BCR2) & BCR2_PORTEN) {
+ printf("\n");
+ panic("shpcic_attach: port enabled");
+ }
+
+ printf(": HITACHI %s\n", spp->sp_name);
+
+ /* allow PCIC request */
+ _reg_write_4(SH4_BCR1, _reg_read_4(SH4_BCR1) | BCR1_BREQEN);
+
+ /* Initialize PCIC */
+ _reg_write_4(SH4_PCICR, PCICR_BASE | PCICR_RSTCTL);
+ delay(10 * 1000);
+ _reg_write_4(SH4_PCICR, PCICR_BASE);
+
+ /* Class: Host-Bridge */
+ _reg_write_4(SH4_PCICONF2,
+ (PCI_CLASS_BRIDGE << PCI_CLASS_SHIFT) |
+ (PCI_SUBCLASS_BRIDGE_HOST << PCI_SUBCLASS_SHIFT));
+
+#if !defined(DONT_INIT_PCIBSC)
+#if defined(PCIBCR_BCR1_VAL)
+ _reg_write_4(SH4_PCIBCR1, PCIBCR_BCR1_VAL);
+#else
+ _reg_write_4(SH4_PCIBCR1, _reg_read_4(SH4_BCR1) | BCR1_MASTER);
+#endif
+#if defined(PCIBCR_BCR2_VAL)
+ _reg_write_4(SH4_PCIBCR2, PCIBCR_BCR2_VAL);
+#else
+ _reg_write_4(SH4_PCIBCR2, _reg_read_2(SH4_BCR2));
+#endif
+#if defined(SH4) && defined(SH7751R)
+ if (cpu_product == CPU_PRODUCT_7751R) {
+#if defined(PCIBCR_BCR3_VAL)
+ _reg_write_4(SH4_PCIBCR3, PCIBCR_BCR3_VAL);
+#else
+ _reg_write_4(SH4_PCIBCR3, _reg_read_2(SH4_BCR3));
+#endif
+ }
+#endif /* SH4 && SH7751R && PCIBCR_BCR3_VAL */
+#if defined(PCIBCR_WCR1_VAL)
+ _reg_write_4(SH4_PCIWCR1, PCIBCR_WCR1_VAL);
+#else
+ _reg_write_4(SH4_PCIWCR1, _reg_read_4(SH4_WCR1));
+#endif
+#if defined(PCIBCR_WCR2_VAL)
+ _reg_write_4(SH4_PCIWCR2, PCIBCR_WCR2_VAL);
+#else
+ _reg_write_4(SH4_PCIWCR2, _reg_read_4(SH4_WCR2));
+#endif
+#if defined(PCIBCR_WCR3_VAL)
+ _reg_write_4(SH4_PCIWCR3, PCIBCR_WCR3_VAL);
+#else
+ _reg_write_4(SH4_PCIWCR3, _reg_read_4(SH4_WCR3));
+#endif
+#if defined(PCIBCR_MCR_VAL)
+ _reg_write_4(SH4_PCIMCR, PCIBCR_MCR_VAL);
+#else
+ _reg_write_4(SH4_PCIMCR, _reg_read_4(SH4_MCR));
+#endif
+#endif /* !DONT_INIT_PCIBSC */
+
+ /* set PCI I/O, memory base address */
+ _reg_write_4(SH4_PCIIOBR, SH4_PCIC_IO);
+ _reg_write_4(SH4_PCIMBR, SH4_PCIC_MEM);
+
+ /* set PCI local address 0 */
+ _reg_write_4(SH4_PCILSR0, (64 - 1) << 20);
+ _reg_write_4(SH4_PCILAR0, 0xac000000);
+ _reg_write_4(SH4_PCICONF5, 0xac000000);
+
+ /* set PCI local address 1 */
+ _reg_write_4(SH4_PCILSR1, (64 - 1) << 20);
+ _reg_write_4(SH4_PCILAR1, 0xac000000);
+ _reg_write_4(SH4_PCICONF6, 0x8c000000);
+
+ /* Enable I/O, memory, bus-master */
+ _reg_write_4(SH4_PCICONF1, PCI_COMMAND_IO_ENABLE
+ | PCI_COMMAND_MEM_ENABLE
+ | PCI_COMMAND_MASTER_ENABLE
+ | PCI_COMMAND_STEPPING_ENABLE
+ | PCI_STATUS_DEVSEL_MEDIUM);
+
+ /* Initialize done. */
+ _reg_write_4(SH4_PCICR, PCICR_BASE | PCICR_CFINIT);
+
+ /* set PCI controller interrupt priority */
+ intpri_intr_priority(SH4_INTEVT_PCIERR, shpcic_intr_priority[0]);
+ intpri_intr_priority(SH4_INTEVT_PCISERR, shpcic_intr_priority[1]);
+
+ /* PCI bus */
+ memset(&pba, 0, sizeof(pba));
+ pba.pba_iot = shpcic_get_bus_io_tag();
+ pba.pba_memt = shpcic_get_bus_mem_tag();
+ pba.pba_dmat = shpcic_get_bus_dma_tag();
+ pba.pba_pc = NULL;
+ pba.pba_bus = 0;
+ pba.pba_bridgetag = NULL;
+ config_found(self, &pba, NULL);
+}
+
+int
+shpcic_bus_maxdevs(void *v, int busno)
+{
+ /*
+ * Bus number is irrelevant. Configuration Mechanism 1 is in
+ * use, can have devices 0-32 (i.e. the `normal' range).
+ */
+ return (32);
+}
+
+pcitag_t
+shpcic_make_tag(void *v, int bus, int device, int function)
+{
+ pcitag_t tag;
+
+ if (bus >= 256 || device >= 32 || function >= 8)
+ panic("pci_make_tag: bad request");
+
+ tag = PCI_MODE1_ENABLE |
+ (bus << 16) | (device << 11) | (function << 8);
+
+ return (tag);
+}
+
+void
+shpcic_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
+{
+ if (bp != NULL)
+ *bp = (tag >> 16) & 0xff;
+ if (dp != NULL)
+ *dp = (tag >> 11) & 0x1f;
+ if (fp != NULL)
+ *fp = (tag >> 8) & 0x7;
+}
+
+pcireg_t
+shpcic_conf_read(void *v, pcitag_t tag, int reg)
+{
+ pcireg_t data;
+ int s;
+
+ s = splhigh();
+ _reg_write_4(SH4_PCIPAR, tag | reg);
+ data = _reg_read_4(SH4_PCIPDR);
+ _reg_write_4(SH4_PCIPAR, 0);
+ splx(s);
+
+ return data;
+}
+
+void
+shpcic_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
+{
+ int s;
+
+ s = splhigh();
+ _reg_write_4(SH4_PCIPAR, tag | reg);
+ _reg_write_4(SH4_PCIPDR, data);
+ _reg_write_4(SH4_PCIPAR, 0);
+ splx(s);
+}
+
+int
+shpcic_set_intr_priority(int intr, int level)
+{
+ int evtcode;
+
+ if ((intr != 0) && (intr != 1)) {
+ return (-1);
+ }
+ if ((level < IPL_NONE) || (level > IPL_HIGH)) {
+ return (-1);
+ }
+
+ if (intr == 0) {
+ evtcode = SH4_INTEVT_PCIERR;
+ } else {
+ evtcode = SH4_INTEVT_PCISERR;
+ }
+
+ intpri_intr_priority(evtcode, shpcic_intr_priority[intr]);
+ shpcic_intr_priority[intr] = level;
+
+ return (0);
+}
+
+void *
+shpcic_intr_establish(int evtcode, int (*ih_func)(void *), void *ih_arg,
+ const char *ih_name)
+{
+ int level;
+
+ switch (evtcode) {
+ case SH4_INTEVT_PCISERR:
+ level = shpcic_intr_priority[1];
+ break;
+
+ case SH4_INTEVT_PCIDMA3:
+ case SH4_INTEVT_PCIDMA2:
+ case SH4_INTEVT_PCIDMA1:
+ case SH4_INTEVT_PCIDMA0:
+ case SH4_INTEVT_PCIPWON:
+ case SH4_INTEVT_PCIPWDWN:
+ case SH4_INTEVT_PCIERR:
+ level = shpcic_intr_priority[0];
+ break;
+
+ default:
+ printf("shpcic_intr_establish: unknown evtcode = 0x%08x\n",
+ evtcode);
+ return NULL;
+ }
+
+ return intc_intr_establish(evtcode, IST_LEVEL, level, ih_func, ih_arg,
+ ih_name);
+}
+
+void
+shpcic_intr_disestablish(void *ih)
+{
+ intc_intr_disestablish(ih);
+}
+
+/*
+ * shpcic bus space
+ */
+int
+shpcic_iomem_map(void *v, bus_addr_t bpa, bus_size_t size,
+ int flags, bus_space_handle_t *bshp)
+{
+ *bshp = (bus_space_handle_t)bpa;
+
+ return (0);
+}
+
+void
+shpcic_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
+{
+ /* Nothing to do */
+}
+
+int
+shpcic_iomem_subregion(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
+{
+ *nbshp = bsh + offset;
+
+ return (0);
+}
+
+int
+shpcic_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
+ bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
+ bus_addr_t *bpap, bus_space_handle_t *bshp)
+{
+ *bshp = *bpap = rstart;
+
+ return (0);
+}
+
+void
+shpcic_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size)
+{
+ /* Nothing to do */
+}
+
+/*
+ * shpcic bus space io/mem read/write
+ */
+/* read */
+static inline uint8_t __shpcic_io_read_1(bus_space_handle_t bsh,
+ bus_size_t offset);
+static inline uint16_t __shpcic_io_read_2(bus_space_handle_t bsh,
+ bus_size_t offset);
+static inline uint32_t __shpcic_io_read_4(bus_space_handle_t bsh,
+ bus_size_t offset);
+static inline uint8_t __shpcic_mem_read_1(bus_space_handle_t bsh,
+ bus_size_t offset);
+static inline uint16_t __shpcic_mem_read_2(bus_space_handle_t bsh,
+ bus_size_t offset);
+static inline uint32_t __shpcic_mem_read_4(bus_space_handle_t bsh,
+ bus_size_t offset);
+
+static inline uint8_t
+__shpcic_io_read_1(bus_space_handle_t bsh, bus_size_t offset)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
+
+ return *(volatile uint8_t *)(SH4_PCIC_IO + adr);
+}
+
+static inline uint16_t
+__shpcic_io_read_2(bus_space_handle_t bsh, bus_size_t offset)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
+
+ return *(volatile uint16_t *)(SH4_PCIC_IO + adr);
+}
+
+static inline uint32_t
+__shpcic_io_read_4(bus_space_handle_t bsh, bus_size_t offset)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
+
+ return *(volatile uint32_t *)(SH4_PCIC_IO + adr);
+}
+
+static inline uint8_t
+__shpcic_mem_read_1(bus_space_handle_t bsh, bus_size_t offset)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
+
+ return *(volatile uint8_t *)(SH4_PCIC_MEM + adr);
+}
+
+static inline uint16_t
+__shpcic_mem_read_2(bus_space_handle_t bsh, bus_size_t offset)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
+
+ return *(volatile uint16_t *)(SH4_PCIC_MEM + adr);
+}
+
+static inline uint32_t
+__shpcic_mem_read_4(bus_space_handle_t bsh, bus_size_t offset)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
+
+ return *(volatile uint32_t *)(SH4_PCIC_MEM + adr);
+}
+
+/*
+ * read single
+ */
+uint8_t
+shpcic_io_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
+{
+ uint8_t value;
+
+ value = __shpcic_io_read_1(bsh, offset);
+
+ return value;
+}
+
+uint16_t
+shpcic_io_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
+{
+ uint16_t value;
+
+ value = __shpcic_io_read_2(bsh, offset);
+
+ return value;
+}
+
+uint32_t
+shpcic_io_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
+{
+ uint32_t value;
+
+ value = __shpcic_io_read_4(bsh, offset);
+
+ return value;
+}
+
+uint8_t
+shpcic_mem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
+{
+ uint8_t value;
+
+ value = __shpcic_mem_read_1(bsh, offset);
+
+ return value;
+}
+
+uint16_t
+shpcic_mem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
+{
+ uint16_t value;
+
+ value = __shpcic_mem_read_2(bsh, offset);
+
+ return value;
+}
+
+uint32_t
+shpcic_mem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
+{
+ uint32_t value;
+
+ value = __shpcic_mem_read_4(bsh, offset);
+
+ return value;
+}
+
+/*
+ * read multi
+ */
+void
+shpcic_io_read_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_io_read_1(bsh, offset);
+ }
+}
+
+void
+shpcic_io_read_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_io_read_2(bsh, offset);
+ }
+}
+
+void
+shpcic_io_read_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_io_read_4(bsh, offset);
+ }
+}
+
+void
+shpcic_mem_read_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_mem_read_1(bsh, offset);
+ }
+}
+
+void
+shpcic_mem_read_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_mem_read_2(bsh, offset);
+ }
+}
+
+void
+shpcic_mem_read_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_mem_read_4(bsh, offset);
+ }
+}
+
+/*
+ *
+ * read region
+ */
+void
+shpcic_io_read_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_io_read_1(bsh, offset);
+ offset += 1;
+ }
+}
+
+void
+shpcic_io_read_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_io_read_2(bsh, offset);
+ offset += 2;
+ }
+}
+
+void
+shpcic_io_read_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_io_read_4(bsh, offset);
+ offset += 4;
+ }
+}
+
+void
+shpcic_mem_read_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_mem_read_1(bsh, offset);
+ offset += 1;
+ }
+}
+
+void
+shpcic_mem_read_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_mem_read_2(bsh, offset);
+ offset += 2;
+ }
+}
+
+void
+shpcic_mem_read_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t *addr, bus_size_t count)
+{
+ while (count--) {
+ *addr++ = __shpcic_mem_read_4(bsh, offset);
+ offset += 4;
+ }
+}
+
+/* write */
+static inline void __shpcic_io_write_1(bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t value);
+static inline void __shpcic_io_write_2(bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t value);
+static inline void __shpcic_io_write_4(bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t value);
+static inline void __shpcic_mem_write_1(bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t value);
+static inline void __shpcic_mem_write_2(bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t value);
+static inline void __shpcic_mem_write_4(bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t value);
+
+static inline void
+__shpcic_io_write_1(bus_space_handle_t bsh, bus_size_t offset,
+ uint8_t value)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
+
+ *(volatile uint8_t *)(SH4_PCIC_IO + adr) = value;
+}
+
+static inline void
+__shpcic_io_write_2(bus_space_handle_t bsh, bus_size_t offset,
+ uint16_t value)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
+
+ *(volatile uint16_t *)(SH4_PCIC_IO + adr) = value;
+}
+
+static inline void
+__shpcic_io_write_4(bus_space_handle_t bsh, bus_size_t offset,
+ uint32_t value)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
+
+ *(volatile uint32_t *)(SH4_PCIC_IO + adr) = value;
+}
+
+static inline void
+__shpcic_mem_write_1(bus_space_handle_t bsh, bus_size_t offset,
+ uint8_t value)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
+
+ *(volatile uint8_t *)(SH4_PCIC_MEM + adr) = value;
+}
+
+static inline void
+__shpcic_mem_write_2(bus_space_handle_t bsh, bus_size_t offset,
+ uint16_t value)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
+
+ *(volatile uint16_t *)(SH4_PCIC_MEM + adr) = value;
+}
+
+static inline void
+__shpcic_mem_write_4(bus_space_handle_t bsh, bus_size_t offset,
+ uint32_t value)
+{
+ u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
+
+ *(volatile uint32_t *)(SH4_PCIC_MEM + adr) = value;
+}
+
+/*
+ * write single
+ */
+void
+shpcic_io_write_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t value)
+{
+ __shpcic_io_write_1(bsh, offset, value);
+}
+
+void
+shpcic_io_write_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t value)
+{
+ __shpcic_io_write_2(bsh, offset, value);
+}
+
+void
+shpcic_io_write_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t value)
+{
+ __shpcic_io_write_4(bsh, offset, value);
+}
+
+void
+shpcic_mem_write_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t value)
+{
+ __shpcic_mem_write_1(bsh, offset, value);
+}
+
+void
+shpcic_mem_write_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t value)
+{
+ __shpcic_mem_write_2(bsh, offset, value);
+}
+
+void
+shpcic_mem_write_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t value)
+{
+ __shpcic_mem_write_4(bsh, offset, value);
+}
+
+/*
+ * write multi
+ */
+void
+shpcic_io_write_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint8_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_1(bsh, offset, *addr++);
+ }
+}
+
+void
+shpcic_io_write_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint16_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_2(bsh, offset, *addr++);
+ }
+}
+
+void
+shpcic_io_write_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint32_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_4(bsh, offset, *addr++);
+ }
+}
+
+void
+shpcic_mem_write_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint8_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_1(bsh, offset, *addr++);
+ }
+}
+
+void
+shpcic_mem_write_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint16_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_2(bsh, offset, *addr++);
+ }
+}
+
+void
+shpcic_mem_write_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint32_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_4(bsh, offset, *addr++);
+ }
+}
+
+/*
+ * write region
+ */
+void
+shpcic_io_write_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint8_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_1(bsh, offset, *addr++);
+ offset += 1;
+ }
+}
+
+void
+shpcic_io_write_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint16_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_2(bsh, offset, *addr++);
+ offset += 2;
+ }
+}
+
+void
+shpcic_io_write_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint32_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_4(bsh, offset, *addr++);
+ offset += 4;
+ }
+}
+
+void
+shpcic_mem_write_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint8_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_1(bsh, offset, *addr++);
+ offset += 1;
+ }
+}
+
+void
+shpcic_mem_write_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint16_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_2(bsh, offset, *addr++);
+ offset += 2;
+ }
+}
+
+void
+shpcic_mem_write_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint32_t *addr, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_4(bsh, offset, *addr++);
+ offset += 4;
+ }
+}
+
+/*
+ * set multi
+ */
+void
+shpcic_io_set_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_1(bsh, offset, value);
+ }
+}
+
+void
+shpcic_io_set_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_2(bsh, offset, value);
+ }
+}
+
+void
+shpcic_io_set_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_4(bsh, offset, value);
+ }
+}
+
+void
+shpcic_mem_set_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_1(bsh, offset, value);
+ }
+}
+
+void
+shpcic_mem_set_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_2(bsh, offset, value);
+ }
+}
+
+void
+shpcic_mem_set_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_4(bsh, offset, value);
+ }
+}
+
+/*
+ * set region
+ */
+void
+shpcic_io_set_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_1(bsh, offset, value);
+ offset += 1;
+ }
+}
+
+void
+shpcic_io_set_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_2(bsh, offset, value);
+ offset += 2;
+ }
+}
+
+void
+shpcic_io_set_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_io_write_4(bsh, offset, value);
+ offset += 4;
+ }
+}
+
+void
+shpcic_mem_set_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_1(bsh, offset, value);
+ offset += 1;
+ }
+}
+
+void
+shpcic_mem_set_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_2(bsh, offset, value);
+ offset += 2;
+ }
+}
+
+void
+shpcic_mem_set_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t value, bus_size_t count)
+{
+ while (count--) {
+ __shpcic_mem_write_4(bsh, offset, value);
+ offset += 4;
+ }
+}
+
+/*
+ * copy region
+ */
+void
+shpcic_io_copy_region_1(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
+{
+ u_long addr1 = bsh1 + off1;
+ u_long addr2 = bsh2 + off2;
+ uint8_t value;
+
+ if (addr1 >= addr2) { /* src after dest: copy forward */
+ while (count--) {
+ value = __shpcic_io_read_1(bsh1, off1);
+ __shpcic_io_write_1(bsh2, off2, value);
+ off1 += 1;
+ off2 += 1;
+ }
+ } else { /* dest after src: copy backwards */
+ off1 += (count - 1) * 1;
+ off2 += (count - 1) * 1;
+ while (count--) {
+ value = __shpcic_io_read_1(bsh1, off1);
+ __shpcic_io_write_1(bsh2, off2, value);
+ off1 -= 1;
+ off2 -= 1;
+ }
+ }
+}
+
+void
+shpcic_io_copy_region_2(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
+{
+ u_long addr1 = bsh1 + off1;
+ u_long addr2 = bsh2 + off2;
+ uint16_t value;
+
+ if (addr1 >= addr2) { /* src after dest: copy forward */
+ while (count--) {
+ value = __shpcic_io_read_2(bsh1, off1);
+ __shpcic_io_write_2(bsh2, off2, value);
+ off1 += 2;
+ off2 += 2;
+ }
+ } else { /* dest after src: copy backwards */
+ off1 += (count - 1) * 2;
+ off2 += (count - 1) * 2;
+ while (count--) {
+ value = __shpcic_io_read_2(bsh1, off1);
+ __shpcic_io_write_2(bsh2, off2, value);
+ off1 -= 2;
+ off2 -= 2;
+ }
+ }
+}
+
+void
+shpcic_io_copy_region_4(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
+{
+ u_long addr1 = bsh1 + off1;
+ u_long addr2 = bsh2 + off2;
+ uint32_t value;
+
+ if (addr1 >= addr2) { /* src after dest: copy forward */
+ while (count--) {
+ value = __shpcic_io_read_4(bsh1, off1);
+ __shpcic_io_write_4(bsh2, off2, value);
+ off1 += 4;
+ off2 += 4;
+ }
+ } else { /* dest after src: copy backwards */
+ off1 += (count - 1) * 4;
+ off2 += (count - 1) * 4;
+ while (count--) {
+ value = __shpcic_io_read_4(bsh1, off1);
+ __shpcic_io_write_4(bsh2, off2, value);
+ off1 -= 4;
+ off2 -= 4;
+ }
+ }
+}
+
+void
+shpcic_mem_copy_region_1(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
+{
+ u_long addr1 = bsh1 + off1;
+ u_long addr2 = bsh2 + off2;
+ uint8_t value;
+
+ if (addr1 >= addr2) { /* src after dest: copy forward */
+ while (count--) {
+ value = __shpcic_mem_read_1(bsh1, off1);
+ __shpcic_mem_write_1(bsh2, off2, value);
+ off1 += 1;
+ off2 += 1;
+ }
+ } else { /* dest after src: copy backwards */
+ off1 += (count - 1) * 1;
+ off2 += (count - 1) * 1;
+ while (count--) {
+ value = __shpcic_mem_read_1(bsh1, off1);
+ __shpcic_mem_write_1(bsh2, off2, value);
+ off1 -= 1;
+ off2 -= 1;
+ }
+ }
+}
+
+void
+shpcic_mem_copy_region_2(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
+{
+ u_long addr1 = bsh1 + off1;
+ u_long addr2 = bsh2 + off2;
+ uint16_t value;
+
+ if (addr1 >= addr2) { /* src after dest: copy forward */
+ while (count--) {
+ value = __shpcic_mem_read_2(bsh1, off1);
+ __shpcic_mem_write_2(bsh2, off2, value);
+ off1 += 2;
+ off2 += 2;
+ }
+ } else { /* dest after src: copy backwards */
+ off1 += (count - 1) * 2;
+ off2 += (count - 1) * 2;
+ while (count--) {
+ value = __shpcic_mem_read_2(bsh1, off1);
+ __shpcic_mem_write_2(bsh2, off2, value);
+ off1 -= 2;
+ off2 -= 2;
+ }
+ }
+}
+
+void
+shpcic_mem_copy_region_4(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
+{
+ u_long addr1 = bsh1 + off1;
+ u_long addr2 = bsh2 + off2;
+ uint32_t value;
+
+ if (addr1 >= addr2) { /* src after dest: copy forward */
+ while (count--) {
+ value = __shpcic_mem_read_4(bsh1, off1);
+ __shpcic_mem_write_4(bsh2, off2, value);
+ off1 += 4;
+ off2 += 4;
+ }
+ } else { /* dest after src: copy backwards */
+ off1 += (count - 1) * 4;
+ off2 += (count - 1) * 4;
+ while (count--) {
+ value = __shpcic_mem_read_4(bsh1, off1);
+ __shpcic_mem_write_4(bsh2, off2, value);
+ off1 -= 4;
+ off2 -= 4;
+ }
+ }
+}
diff --git a/sys/arch/sh/dev/shpcicvar.h b/sys/arch/sh/dev/shpcicvar.h
new file mode 100644
index 00000000000..f000fec3084
--- /dev/null
+++ b/sys/arch/sh/dev/shpcicvar.h
@@ -0,0 +1,184 @@
+/* $OpenBSD: shpcicvar.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: shpcicvar.h,v 1.6 2005/12/11 12:18:58 christos Exp $ */
+
+/*-
+ * Copyright (c) 2005 NONAKA Kimihiro
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/bus.h>
+
+bus_space_tag_t shpcic_get_bus_io_tag(void);
+bus_space_tag_t shpcic_get_bus_mem_tag(void);
+bus_dma_tag_t shpcic_get_bus_dma_tag(void);
+
+int shpcic_bus_maxdevs(void *v, int busno);
+pcitag_t shpcic_make_tag(void *v, int bus, int device, int function);
+void shpcic_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp);
+pcireg_t shpcic_conf_read(void *v, pcitag_t tag, int reg);
+void shpcic_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data);
+
+int shpcic_set_intr_priority(int intr, int level);
+void *shpcic_intr_establish(int evtcode, int (*ih_func)(void *), void *ih_arg,
+ const char *ih_name);
+void shpcic_intr_disestablish(void *ih);
+
+/*
+ * shpcic io/mem bus space
+ */
+int shpcic_iomem_map(void *v, bus_addr_t bpa, bus_size_t size, int flags,
+ bus_space_handle_t *bshp);
+void shpcic_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size);
+int shpcic_iomem_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset,
+ bus_size_t size, bus_space_handle_t *nbshp);
+int shpcic_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
+ bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
+ bus_addr_t *bpap, bus_space_handle_t *bshp);
+void shpcic_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size);
+
+/* read single */
+uint8_t shpcic_io_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset);
+uint16_t shpcic_io_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset);
+uint32_t shpcic_io_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset);
+uint8_t shpcic_mem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset);
+uint16_t shpcic_mem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset);
+uint32_t shpcic_mem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset);
+
+/* read multi */
+void shpcic_io_read_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t *addr, bus_size_t count);
+void shpcic_io_read_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t *addr, bus_size_t count);
+void shpcic_io_read_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t *addr, bus_size_t count);
+void shpcic_mem_read_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t *addr, bus_size_t count);
+void shpcic_mem_read_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t *addr, bus_size_t count);
+void shpcic_mem_read_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t *addr, bus_size_t count);
+
+/* read region */
+void shpcic_io_read_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t *addr, bus_size_t count);
+void shpcic_io_read_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t *addr, bus_size_t count);
+void shpcic_io_read_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t *addr, bus_size_t count);
+void shpcic_mem_read_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t *addr, bus_size_t count);
+void shpcic_mem_read_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t *addr, bus_size_t count);
+void shpcic_mem_read_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t *addr, bus_size_t count);
+
+/* write single */
+void shpcic_io_write_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t data);
+void shpcic_io_write_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t data);
+void shpcic_io_write_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t data);
+void shpcic_mem_write_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t data);
+void shpcic_mem_write_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t data);
+void shpcic_mem_write_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t data);
+
+/* write multi */
+void shpcic_io_write_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint8_t *addr, bus_size_t count);
+void shpcic_io_write_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint16_t *addr, bus_size_t count);
+void shpcic_io_write_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint32_t *addr, bus_size_t count);
+void shpcic_mem_write_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint8_t *addr, bus_size_t count);
+void shpcic_mem_write_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint16_t *addr, bus_size_t count);
+void shpcic_mem_write_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint32_t *addr, bus_size_t count);
+
+/* write region */
+void shpcic_io_write_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint8_t *addr, bus_size_t count);
+void shpcic_io_write_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint16_t *addr, bus_size_t count);
+void shpcic_io_write_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint32_t *addr, bus_size_t count);
+void shpcic_mem_write_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint8_t *addr, bus_size_t count);
+void shpcic_mem_write_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint16_t *addr, bus_size_t count);
+void shpcic_mem_write_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, const uint32_t *addr, bus_size_t count);
+
+/* set multi */
+void shpcic_io_set_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t val, bus_size_t count);
+void shpcic_io_set_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t val, bus_size_t count);
+void shpcic_io_set_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t val, bus_size_t count);
+void shpcic_mem_set_multi_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t val, bus_size_t count);
+void shpcic_mem_set_multi_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t val, bus_size_t count);
+void shpcic_mem_set_multi_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t val, bus_size_t count);
+
+/* set region */
+void shpcic_io_set_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t val, bus_size_t count);
+void shpcic_io_set_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t val, bus_size_t count);
+void shpcic_io_set_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t val, bus_size_t count);
+void shpcic_mem_set_region_1(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint8_t val, bus_size_t count);
+void shpcic_mem_set_region_2(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint16_t val, bus_size_t count);
+void shpcic_mem_set_region_4(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, uint32_t val, bus_size_t count);
+
+/* copy region */
+void shpcic_io_copy_region_1(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2,
+ bus_size_t count);
+void shpcic_io_copy_region_2(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2,
+ bus_size_t count);
+void shpcic_io_copy_region_4(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2,
+ bus_size_t count);
+void shpcic_mem_copy_region_1(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2,
+ bus_size_t count);
+void shpcic_mem_copy_region_2(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2,
+ bus_size_t count);
+void shpcic_mem_copy_region_4(void *v, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2,
+ bus_size_t count);
diff --git a/sys/arch/sh/include/_types.h b/sys/arch/sh/include/_types.h
new file mode 100644
index 00000000000..8b528bbf524
--- /dev/null
+++ b/sys/arch/sh/include/_types.h
@@ -0,0 +1,121 @@
+/* $OpenBSD: _types.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)types.h 8.3 (Berkeley) 1/5/94
+ * @(#)ansi.h 8.2 (Berkeley) 1/4/94
+ */
+
+#ifndef _SH__TYPES_H_
+#define _SH__TYPES_H_
+
+#if defined(_KERNEL)
+typedef struct label_t {
+ int val[9];
+} label_t;
+#endif
+
+/* 7.18.1.1 Exact-width integer types */
+typedef __signed char __int8_t;
+typedef unsigned char __uint8_t;
+typedef short __int16_t;
+typedef unsigned short __uint16_t;
+typedef int __int32_t;
+typedef unsigned int __uint32_t;
+/* LONGLONG */
+typedef long long __int64_t;
+/* LONGLONG */
+typedef unsigned long long __uint64_t;
+
+/* 7.18.1.2 Minimum-width integer types */
+typedef __int8_t __int_least8_t;
+typedef __uint8_t __uint_least8_t;
+typedef __int16_t __int_least16_t;
+typedef __uint16_t __uint_least16_t;
+typedef __int32_t __int_least32_t;
+typedef __uint32_t __uint_least32_t;
+typedef __int64_t __int_least64_t;
+typedef __uint64_t __uint_least64_t;
+
+/* 7.18.1.3 Fastest minimum-width integer types */
+typedef __int32_t __int_fast8_t;
+typedef __uint32_t __uint_fast8_t;
+typedef __int32_t __int_fast16_t;
+typedef __uint32_t __uint_fast16_t;
+typedef __int32_t __int_fast32_t;
+typedef __uint32_t __uint_fast32_t;
+typedef __int64_t __int_fast64_t;
+typedef __uint64_t __uint_fast64_t;
+
+/* 7.18.1.4 Integer types capable of holding object pointers */
+typedef long __intptr_t;
+typedef unsigned long __uintptr_t;
+
+/* 7.18.1.5 Greatest-width integer types */
+typedef __int64_t __intmax_t;
+typedef __uint64_t __uintmax_t;
+
+/* Register size */
+typedef __uint32_t __register_t;
+
+/* VM system types */
+typedef unsigned long __vaddr_t;
+typedef unsigned long __paddr_t;
+typedef unsigned long __vsize_t;
+typedef unsigned long __psize_t;
+
+/* Standard system types */
+typedef int __clock_t;
+typedef int __clockid_t;
+typedef long long __off_t;
+typedef long __ptrdiff_t;
+typedef unsigned long __size_t;
+typedef long __ssize_t;
+typedef int __time_t;
+typedef int __timer_t;
+#if defined(__GNUC__) && __GNUC__ >= 3
+typedef __builtin_va_list __va_list;
+#else
+struct __va_list_tag;
+typedef struct __va_list_tag * __va_list;
+#endif
+
+/* Wide character support types */
+#ifndef __cplusplus
+typedef int __wchar_t;
+#endif
+typedef int __wint_t;
+typedef int __rune_t;
+typedef void * __wctrans_t;
+typedef void * __wctype_t;
+
+/* Feature test macros */
+#define __HAVE_GENERIC_SOFT_INTERRUPTS
+
+#endif /* _SH__TYPES_H_ */
diff --git a/sys/arch/sh/include/asm.h b/sys/arch/sh/include/asm.h
new file mode 100644
index 00000000000..052d5a1748a
--- /dev/null
+++ b/sys/arch/sh/include/asm.h
@@ -0,0 +1,217 @@
+/* $OpenBSD: asm.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: asm.h,v 1.25 2006/01/20 22:02:40 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)asm.h 5.5 (Berkeley) 5/7/91
+ */
+
+#ifndef _SH_ASM_H_
+#define _SH_ASM_H_
+
+#ifdef __ELF__
+# define _C_LABEL(x) x
+#else
+#ifdef __STDC__
+# define _C_LABEL(x) _ ## x
+#else
+# define _C_LABEL(x) _/**/x
+#endif
+#endif
+#define _ASM_LABEL(x) x
+
+#ifdef __STDC__
+# define __CONCAT(x,y) x ## y
+# define __STRING(x) #x
+#else
+# define __CONCAT(x,y) x/**/y
+# define __STRING(x) "x"
+#endif
+
+/* let kernels and others override entrypoint alignment */
+#ifndef _ALIGN_TEXT
+# define _ALIGN_TEXT .align 2
+#endif
+
+#ifdef __ELF__
+#define _ENTRY(x) \
+ .text ;\
+ _ALIGN_TEXT ;\
+ .globl x ;\
+ .type x,@function ;\
+ x:
+#else /* !__ELF__ */
+#define _ENTRY(x) \
+ .text ;\
+ _ALIGN_TEXT ;\
+ .globl x ;\
+ x:
+#endif /* !__ELF__ */
+
+#ifdef GPROF
+#define _PROF_PROLOGUE \
+ mov.l 1f,r1 ; \
+ mova 2f,r0 ; \
+ jmp @r1 ; \
+ nop ; \
+ .align 2 ; \
+1: .long __mcount ; \
+2:
+#else /* !GPROF */
+#define _PROF_PROLOGUE
+#endif /* !GPROF */
+
+#define ENTRY(y) _ENTRY(_C_LABEL(y)) _PROF_PROLOGUE
+#define NENTRY(y) _ENTRY(_C_LABEL(y))
+#define ASENTRY(y) _ENTRY(_ASM_LABEL(y)) _PROF_PROLOGUE
+
+#define SET_ENTRY_SIZE(y) \
+ .size _C_LABEL(y), . - _C_LABEL(y)
+
+#define SET_ASENTRY_SIZE(y) \
+ .size _ASM_LABEL(y), . - _ASM_LABEL(y)
+
+#ifdef __ELF__
+#define ALTENTRY(name) \
+ .globl _C_LABEL(name) ;\
+ .type _C_LABEL(name),@function ;\
+ _C_LABEL(name):
+#else
+#define ALTENTRY(name) \
+ .globl _C_LABEL(name) ;\
+ _C_LABEL(name):
+#endif
+
+
+/*
+ * Hide the gory details of PIC calls vs. normal calls. Use as in the
+ * following example:
+ *
+ * sts.l pr, @-sp
+ * PIC_PROLOGUE(.L_got, r0) ! saves old r12 on stack
+ * ...
+ * mov.l .L_function_1, r0
+ * 1: CALL r0 ! each call site needs a label
+ * nop
+ * ...
+ * mov.l .L_function_2, r0
+ * 2: CALL r0
+ * nop
+ * ...
+ * PIC_EPILOGUE ! restores r12 from stack
+ * lds.l @sp+, pr ! so call in right order
+ * rts
+ * nop
+ *
+ * .align 2
+ * .L_got:
+ * PIC_GOT_DATUM
+ * .L_function_1: ! if you call the same function twice
+ * CALL_DATUM(function, 1b) ! provide call datum for each call
+ * .L_function_2:
+ * CALL_DATUM(function, 2b)
+ */
+
+#ifdef PIC
+
+#define PIC_PLT(x) x@PLT
+#define PIC_GOT(x) x@GOT
+#define PIC_GOTOFF(x) x@GOTOFF
+
+#define PIC_PROLOGUE(got) \
+ mov.l r12, @-sp; \
+ PIC_PROLOGUE_NOSAVE(got)
+
+/*
+ * Functions that do non local jumps don't need to preserve r12,
+ * so we can shave off two instructions to save/restore it.
+ */
+#define PIC_PROLOGUE_NOSAVE(got) \
+ mov.l got, r12; \
+ mova got, r0; \
+ add r0, r12
+
+#define PIC_EPILOGUE \
+ mov.l @sp+, r12
+
+#define PIC_EPILOGUE_SLOT \
+ PIC_EPILOGUE
+
+#define PIC_GOT_DATUM \
+ .long _GLOBAL_OFFSET_TABLE_
+
+#define CALL bsrf
+#define JUMP braf
+
+#define CALL_DATUM(function, lpcs) \
+ .long PIC_PLT(function) - ((lpcs) + 4 - (.))
+
+/*
+ * This will result in text relocations in the shared library,
+ * unless the function is local or has hidden or protected visibility.
+ * Does not require PIC prologue.
+ */
+#define CALL_DATUM_LOCAL(function, lpcs) \
+ .long function - ((lpcs) + 4)
+
+#else /* !PIC */
+
+#define PIC_PROLOGUE(label)
+#define PIC_PROLOGUE_NOSAVE(label)
+#define PIC_EPILOGUE
+#define PIC_EPILOGUE_SLOT nop
+#define PIC_GOT_DATUM
+
+#define CALL jsr @
+#define JUMP jmp @
+
+#define CALL_DATUM(function, lpcs) \
+ .long function
+
+#define CALL_DATUM_LOCAL(function, lpcs) \
+ .long function
+
+#endif /* !PIC */
+
+
+#define ASMSTR .asciz
+
+#ifdef __ELF__
+#define WEAK_ALIAS(alias,sym) \
+ .weak _C_LABEL(alias); \
+ _C_LABEL(alias) = _C_LABEL(sym)
+#endif
+
+#define WARN_REFERENCES(_sym,_msg) \
+ .section .gnu.warning._sym; .ascii _msg; .previous
+
+#endif /* !_SH_ASM_H_ */
diff --git a/sys/arch/sh/include/bscreg.h b/sys/arch/sh/include/bscreg.h
new file mode 100644
index 00000000000..86ea687978d
--- /dev/null
+++ b/sys/arch/sh/include/bscreg.h
@@ -0,0 +1,70 @@
+/* $OpenBSD: bscreg.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: bscreg.h,v 1.6 2005/12/11 12:18:58 christos Exp $ */
+
+/*-
+ * Copyright (C) 1999 SAITOH Masanobu. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SH_BSCREG_H_
+#define _SH_BSCREG_H_
+#include <sh/devreg.h>
+
+/*
+ * Bus State Controller
+ */
+
+#define SH3_BCR1 0xffffff60 /* 16bit */
+#define SH3_BCR2 0xffffff62 /* 16bit */
+#define SH3_WCR1 0xffffff64 /* 16bit */
+#define SH3_WCR2 0xffffff66 /* 16bit */
+#define SH3_MCR 0xffffff68 /* 16bit */
+#define SH3_DCR 0xffffff6a /* 16bit */
+#define SH3_PCR 0xffffff6c /* 16bit */
+#define SH3_RTCSR 0xffffff6e /* 16bit */
+#define SH3_RTCNT 0xffffff70 /* 16bit */
+#define SH3_RTCOR 0xffffff72 /* 16bit */
+#define SH3_RFCR 0xffffff74 /* 16bit */
+#define SH3_BCR3 0xffffff7e /* 16bit */
+
+#define SH4_BCR1 0xff800000 /* 32bit */
+#define SH4_BCR2 0xff800004 /* 16bit */
+#define SH4_WCR1 0xff800008 /* 32bit */
+#define SH4_WCR2 0xff80000c /* 32bit */
+#define SH4_WCR3 0xff800010 /* 32bit */
+#define SH4_MCR 0xff800014 /* 32bit */
+#define SH4_PCR 0xff800018 /* 16bit */
+#define SH4_RTCSR 0xff80001c /* 16bit */
+#define SH4_RTCNT 0xff800020 /* 16bit */
+#define SH4_RTCOR 0xff800024 /* 16bit */
+#define SH4_RFCR 0xff800028 /* 16bit */
+#define SH4_BCR3 0xff800050 /* 16bit: SH7751R */
+#define SH4_BCR4 0xfe0a00f0 /* 32bit: SH7751R */
+
+#define BCR1_MASTER (1 << 30)
+#define BCR1_BREQEN (1 << 19)
+
+#define BCR2_PORTEN (1 << 0)
+
+#endif /* !_SH_BSCREG_H_ */
diff --git a/sys/arch/sh/include/cache.h b/sys/arch/sh/include/cache.h
new file mode 100644
index 00000000000..2e4fa50249a
--- /dev/null
+++ b/sys/arch/sh/include/cache.h
@@ -0,0 +1,194 @@
+/* $OpenBSD: cache.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: cache.h,v 1.7 2006/01/21 00:46:36 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+/*
+ * Cache configurations.
+ *
+ * SH3 I/D unified virtual-index physical-tag cache.
+ * SH4 I/D separated virtual-index physical-tag cache.
+ *
+ *
+ * size line-size entry way type
+ * SH7708 4/8K 16B 128 2/4 P0,P2,U0 [1]
+ * P1 [2]
+ * SH7709 4/8K 16B 128 2/4 [1]
+ * SH7709A 16K 16B 256 4 [1]
+ *
+ * SH7750 I$ D$ line-size entry way
+ * 8K 8/16K 32B 256 1 [1]
+ * SH7750
+ * SH7750S
+ * SH7751 I$ D$ line-size entry way
+ * 8K 8/16K 32B 256 1 [1]
+ *
+ * SH7750R
+ * SH7751R I$ D$ line-size entry way
+ * 16K 16/32K 32B 512 2 [1]
+ *
+ * [1] write-through/back selectable
+ * [2] write-through only
+ *
+ * Cache operations.
+ *
+ * There are some rules that must be followed:
+ *
+ * I-cache Sync (all or range):
+ * The goal is to synchronize the instruction stream,
+ * so you may need to write-back dirty data cache
+ * blocks first. If a range is requested, and you
+ * can't synchronize just a range, you have to hit
+ * the whole thing.
+ *
+ * D-cache Write-back Invalidate range:
+ * If you can't WB-Inv a range, you must WB-Inv the
+ * entire D-cache.
+ *
+ * D-cache Invalidate:
+ * If you can't Inv the D-cache without doing a
+ * Write-back, YOU MUST PANIC. This is to catch
+ * errors in calling code. Callers must be aware
+ * of this scenario, and must handle it appropriately
+ * (consider the bus_dma(9) operations).
+ *
+ * D-cache Write-back:
+ * If you can't Write-back without doing an invalidate,
+ * that's fine. Then treat this as a WB-Inv. Skipping
+ * the invalidate is merely an optimization.
+ *
+ * All operations:
+ * Valid virtual addresses must be passed to the
+ * cache operation.
+ *
+ *
+ * sh_icache_sync_all Synchronize I-cache
+ *
+ * sh_icache_sync_range Synchronize I-cache range
+ *
+ * sh_icache_sync_range_index (index ops)
+ *
+ * sh_dcache_wbinv_all Write-back Invalidate D-cache
+ *
+ * sh_dcache_wbinv_range Write-back Invalidate D-cache range
+ *
+ * sh_dcache_wbinv_range_index (index ops)
+ *
+ * sh_dcache_inv_range Invalidate D-cache range
+ *
+ * sh_dcache_wb_range Write-back D-cache range
+ *
+ * If I/D unified cache (SH3), I-cache ops are writeback invalidate
+ * operation.
+ * If write-through mode, sh_dcache_wb_range is no-operation.
+ *
+ */
+
+#ifndef _SH_CACHE_H_
+#define _SH_CACHE_H_
+
+#ifdef _KERNEL
+struct sh_cache_ops {
+ void (*_icache_sync_all)(void);
+ void (*_icache_sync_range)(vaddr_t, vsize_t);
+ void (*_icache_sync_range_index)(vaddr_t, vsize_t);
+
+ void (*_dcache_wbinv_all)(void);
+ void (*_dcache_wbinv_range)(vaddr_t, vsize_t);
+ void (*_dcache_wbinv_range_index)(vaddr_t, vsize_t);
+ void (*_dcache_inv_range)(vaddr_t, vsize_t);
+ void (*_dcache_wb_range)(vaddr_t, vsize_t);
+};
+
+/* Cache configurations */
+#define sh_cache_enable_unified sh_cache_enable_icache
+extern int sh_cache_enable_icache;
+extern int sh_cache_enable_dcache;
+extern int sh_cache_write_through;
+extern int sh_cache_write_through_p0_u0_p3;
+extern int sh_cache_write_through_p1;
+extern int sh_cache_ways;
+extern int sh_cache_unified;
+#define sh_cache_size_unified sh_cache_size_icache
+extern int sh_cache_size_icache;
+extern int sh_cache_size_dcache;
+extern int sh_cache_line_size;
+/* for n-way set associative cache */
+extern int sh_cache_way_size;
+extern int sh_cache_way_shift;
+extern int sh_cache_entry_mask;
+
+/* Special mode */
+extern int sh_cache_ram_mode;
+extern int sh_cache_index_mode_icache;
+extern int sh_cache_index_mode_dcache;
+
+extern struct sh_cache_ops sh_cache_ops;
+
+#define sh_icache_sync_all() \
+ (*sh_cache_ops._icache_sync_all)()
+
+#define sh_icache_sync_range(v, s) \
+ (*sh_cache_ops._icache_sync_range)((v), (s))
+
+#define sh_icache_sync_range_index(v, s) \
+ (*sh_cache_ops._icache_sync_range_index)((v), (s))
+
+#define sh_dcache_wbinv_all() \
+ (*sh_cache_ops._dcache_wbinv_all)()
+
+#define sh_dcache_wbinv_range(v, s) \
+ (*sh_cache_ops._dcache_wbinv_range)((v), (s))
+
+#define sh_dcache_wbinv_range_index(v, s) \
+ (*sh_cache_ops._dcache_wbinv_range_index)((v), (s))
+
+#define sh_dcache_inv_range(v, s) \
+ (*sh_cache_ops._dcache_inv_range)((v), (s))
+
+#define sh_dcache_wb_range(v, s) \
+ (*sh_cache_ops._dcache_wb_range)((v), (s))
+
+void sh_cache_init(void);
+void sh_cache_information(void);
+
+#define SH_HAS_UNIFIED_CACHE CPU_IS_SH3
+#define SH_HAS_VIRTUAL_ALIAS CPU_IS_SH4
+#define SH_HAS_WRITEBACK_CACHE (!sh_cache_write_through)
+
+#endif /* _KERNEL */
+#endif /* _SH_CACHE_H_ */
diff --git a/sys/arch/sh/include/cache_sh3.h b/sys/arch/sh/include/cache_sh3.h
new file mode 100644
index 00000000000..b51e1c469b5
--- /dev/null
+++ b/sys/arch/sh/include/cache_sh3.h
@@ -0,0 +1,159 @@
+/* $OpenBSD: cache_sh3.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: cache_sh3.h,v 1.8 2006/03/04 01:55:03 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+/*
+ * SH3: SH7708, SH7708S, SH7708R, SH7709, SH7709A
+ */
+#ifndef _SH_CACHE_SH3_H_
+#define _SH_CACHE_SH3_H_
+#include <sh/devreg.h>
+#ifdef _KERNEL
+
+#define SH3_CCR 0xffffffec
+#define SH3_CCR_CE 0x00000001
+#define SH3_CCR_WT 0x00000002
+/* SH7708 don't have CB bit */
+#define SH3_CCR_CB 0x00000004
+#define SH3_CCR_CF 0x00000008
+/* SH7709A don't have RA bit */
+#define SH3_CCR_RA 0x00000020
+
+/* SH7709A specific cache-lock control register */
+#define SH7709A_CCR2 0xa40000b0
+#define SH7709A_CCR2_W2LOCK 0x00000001
+#define SH7709A_CCR2_W2LOAD 0x00000002
+#define SH7709A_CCR2_W3LOCK 0x00000100
+#define SH7709A_CCR2_W3LOAD 0x00000200
+
+#define SH3_CCA 0xf0000000
+/* Address specification */
+#define CCA_A 0x00000008
+#define CCA_ENTRY_SHIFT 4
+/* 8KB cache (SH7708, SH7708S, SH7708R, SH7709) */
+#define CCA_8K_ENTRY 128
+#define CCA_8K_ENTRY_MASK 0x000007f0 /* [10:4] */
+#define CCA_8K_WAY_SHIFT 11
+#define CCA_8K_WAY_MASK 0x00001800 /* [12:11] */
+/* 16KB cache (SH7709A) */
+#define CCA_16K_ENTRY 256
+#define CCA_16K_ENTRY_MASK 0x00000ff0 /* [11:4] */
+#define CCA_16K_WAY_SHIFT 12
+#define CCA_16K_WAY_MASK 0x00003000 /* [13:12] */
+
+/* Data specification */
+#define CCA_V 0x00000001
+#define CCA_U 0x00000002
+#define CCA_LRU_SHIFT 4
+#define CCA_LRU_MASK 0x000003f0 /* [9:4] */
+#define CCA_TAGADDR_SHIFT 10
+#define CCA_TAGADDR_MASK 0xfffffc00 /* [31:10] */
+
+#define SH3_CCD 0xf1000000
+/* Address specification */
+#define CCD_L_SHIFT 2
+#define CCD_L_MASK 0x0000000c /* [3:2] */
+#define CCD_E_SHIFT 4
+#define CCD_8K_E_MASK 0x000007f0 /* [10:4] */
+#define CCD_16K_E_MASK 0x00000ff0 /* [11:4] */
+#define CCD_8K_W_SHIFT 11
+#define CCD_8K_W_MASK 0x00001800 /* [12:11] */
+#define CCD_16K_W_SHIFT 12
+#define CCD_16K_W_MASK 0x00003000 /* [13:12] */
+/* Data specification */
+
+/*
+ * Configuration
+ */
+#define SH3_CACHE_LINESZ 16
+#define SH3_CACHE_NORMAL_WAY 4
+#define SH3_CACHE_RAMMODE_WAY 2
+
+#define SH3_CACHE_8K_ENTRY 128
+#define SH3_CACHE_8K_WAY_NORMAL 4
+#define SH3_CACHE_8K_WAY_RAMMODE 2
+
+#define SH3_CACHE_16K_ENTRY 256
+#define SH3_CACHE_16K_WAY 4
+
+/*
+ * cache flush macro for locore level code.
+ */
+#define SH3_CACHE_8K_FLUSH(maxway) \
+do { \
+ uint32_t __e, __w, __wa, __a; \
+ \
+ for (__w = 0; __w < maxway; __w++) { \
+ __wa = SH3_CCA | __w << CCA_8K_WAY_SHIFT; \
+ for (__e = 0; __e < CCA_8K_ENTRY; __e++) { \
+ __a = __wa |(__e << CCA_ENTRY_SHIFT); \
+ (*(volatile uint32_t *)__a) &= \
+ ~(CCA_U | CCA_V); \
+ } \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SH3_CACHE_16K_FLUSH() \
+do { \
+ uint32_t __e, __w, __wa, __a; \
+ \
+ for (__w = 0; __w < SH3_CACHE_16K_WAY; __w++) { \
+ __wa = SH3_CCA | __w << CCA_16K_WAY_SHIFT; \
+ for (__e = 0; __e < CCA_16K_ENTRY; __e++) { \
+ __a = __wa |(__e << CCA_ENTRY_SHIFT); \
+ (*(volatile uint32_t *)__a) &= \
+ ~(CCA_U | CCA_V); \
+ } \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SH7708_CACHE_FLUSH() SH3_CACHE_8K_FLUSH(4)
+#define SH7708_CACHE_FLUSH_RAMMODE() SH3_CACHE_8K_FLUSH(2)
+#define SH7708S_CACHE_FLUSH() SH3_CACHE_8K_FLUSH(4)
+#define SH7708S_CACHE_FLUSH_RAMMODE() SH3_CACHE_8K_FLUSH(2)
+#define SH7708R_CACHE_FLUSH() SH3_CACHE_8K_FLUSH(4)
+#define SH7708R_CACHE_FLUSH_RAMMODE() SH3_CACHE_8K_FLUSH(2)
+#define SH7709_CACHE_FLUSH() SH3_CACHE_8K_FLUSH(4)
+#define SH7709_CACHE_FLUSH_RAMMODE() SH3_CACHE_8K_FLUSH(2)
+#define SH7709A_CACHE_FLUSH() SH3_CACHE_16K_FLUSH()
+
+#ifndef _LOCORE
+extern void sh3_cache_config(void);
+#endif
+#endif /* _KERNEL */
+#endif /* !_SH_CACHE_SH3_H_ */
diff --git a/sys/arch/sh/include/cache_sh4.h b/sys/arch/sh/include/cache_sh4.h
new file mode 100644
index 00000000000..dfc5ff14434
--- /dev/null
+++ b/sys/arch/sh/include/cache_sh4.h
@@ -0,0 +1,155 @@
+/* $OpenBSD: cache_sh4.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: cache_sh4.h,v 1.11 2006/03/04 01:55:03 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+/*
+ * SH4: SH7750 SH7750S SH7750R SH7751 SH7751R
+ */
+
+#ifndef _SH_CACHE_SH4_H_
+#define _SH_CACHE_SH4_H_
+#include <sh/devreg.h>
+#ifdef _KERNEL
+
+#define SH4_ICACHE_SIZE 8192
+#define SH4_DCACHE_SIZE 16384
+#define SH4_EMODE_ICACHE_SIZE 16384
+#define SH4_EMODE_DCACHE_SIZE 32768
+#define SH4_CACHE_LINESZ 32
+
+#define SH4_CCR 0xff00001c
+#define SH4_CCR_EMODE 0x80000000
+#define SH4_CCR_IIX 0x00008000
+#define SH4_CCR_ICI 0x00000800
+#define SH4_CCR_ICE 0x00000100
+#define SH4_CCR_OIX 0x00000080
+#define SH4_CCR_ORA 0x00000020
+#define SH4_CCR_OCI 0x00000008
+#define SH4_CCR_CB 0x00000004
+#define SH4_CCR_WT 0x00000002
+#define SH4_CCR_OCE 0x00000001
+
+#define SH4_QACR0 0xff000038
+#define SH4_QACR1 0xff00003c
+#define SH4_QACR_AREA_SHIFT 2
+#define SH4_QACR_AREA_MASK 0x0000001c
+
+/* I-cache address/data array */
+#define SH4_CCIA 0xf0000000
+/* address specification */
+#define CCIA_A 0x00000008 /* associate bit */
+#define CCIA_ENTRY_SHIFT 5 /* line size 32B */
+#define CCIA_ENTRY_MASK 0x00001fe0 /* [12:5] 256-entries */
+#define CCIA_EMODE_ENTRY_MASK 0x00003fe0 /* [13:5] 512-entries */
+/* data specification */
+#define CCIA_V 0x00000001
+#define CCIA_TAGADDR_MASK 0xfffffc00 /* [31:10] */
+
+#define SH4_CCID 0xf1000000
+/* address specification */
+#define CCID_L_SHIFT 2
+#define CCID_L_MASK 0x1c /* line-size is 32B */
+#define CCID_ENTRY_MASK 0x00001fe0 /* [12:5] 256-entries */
+
+/* D-cache address/data array */
+#define SH4_CCDA 0xf4000000
+/* address specification */
+#define CCDA_A 0x00000008 /* associate bit */
+#define CCDA_ENTRY_SHIFT 5 /* line size 32B */
+#define CCDA_ENTRY_MASK 0x00003fe0 /* [13:5] 512-entries */
+/* data specification */
+#define CCDA_V 0x00000001
+#define CCDA_U 0x00000002
+#define CCDA_TAGADDR_MASK 0xfffffc00 /* [31:10] */
+
+#define SH4_CCDD 0xf5000000
+
+/* Store Queue */
+#define SH4_SQ 0xe0000000
+
+/*
+ * cache flush macro for locore level code.
+ */
+#define SH4_CACHE_FLUSH() \
+do { \
+ uint32_t __e, __a; \
+ \
+ /* D-cache */ \
+ for (__e = 0; __e < (SH4_DCACHE_SIZE / SH4_CACHE_LINESZ); __e++) {\
+ __a = SH4_CCDA | (__e << CCDA_ENTRY_SHIFT); \
+ (*(volatile uint32_t *)__a) &= ~(CCDA_U | CCDA_V); \
+ } \
+ /* I-cache */ \
+ for (__e = 0; __e < (SH4_ICACHE_SIZE / SH4_CACHE_LINESZ); __e++) {\
+ __a = SH4_CCIA | (__e << CCIA_ENTRY_SHIFT); \
+ (*(volatile uint32_t *)__a) &= ~(CCIA_V); \
+ } \
+} while(/*CONSTCOND*/0)
+
+#define SH4_EMODE_CACHE_FLUSH() \
+do { \
+ uint32_t __e, __a; \
+ \
+ /* D-cache */ \
+ for (__e = 0;__e < (SH4_EMODE_DCACHE_SIZE / SH4_CACHE_LINESZ);__e++) {\
+ __a = SH4_CCDA | (__e << CCDA_ENTRY_SHIFT); \
+ (*(volatile uint32_t *)__a) &= ~(CCDA_U | CCDA_V); \
+ } \
+ /* I-cache */ \
+ for (__e = 0;__e < (SH4_EMODE_ICACHE_SIZE / SH4_CACHE_LINESZ);__e++) {\
+ __a = SH4_CCIA | (__e << CCIA_ENTRY_SHIFT); \
+ (*(volatile uint32_t *)__a) &= ~(CCIA_V); \
+ } \
+} while(/*CONSTCOND*/0)
+
+#define SH7750_CACHE_FLUSH() SH4_CACHE_FLUSH()
+#define SH7750S_CACHE_FLUSH() SH4_CACHE_FLUSH()
+#define SH7751_CACHE_FLUSH() SH4_CACHE_FLUSH()
+#if defined(SH4_CACHE_DISABLE_EMODE)
+#define SH7750R_CACHE_FLUSH() SH4_CACHE_FLUSH()
+#define SH7751R_CACHE_FLUSH() SH4_CACHE_FLUSH()
+#else
+#define SH7750R_CACHE_FLUSH() SH4_EMODE_CACHE_FLUSH()
+#define SH7751R_CACHE_FLUSH() SH4_EMODE_CACHE_FLUSH()
+#endif
+
+#ifndef _LOCORE
+extern void sh4_cache_config(void);
+#endif
+#endif /* _KERNEL */
+#endif /* !_SH_CACHE_SH4_H_ */
diff --git a/sys/arch/sh/include/cdefs.h b/sys/arch/sh/include/cdefs.h
new file mode 100644
index 00000000000..eb7c7eb3761
--- /dev/null
+++ b/sys/arch/sh/include/cdefs.h
@@ -0,0 +1,19 @@
+/* $OpenBSD: cdefs.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+
+#ifndef _SH_CDEFS_H_
+#define _SH_CDEFS_H_
+
+#if defined(lint)
+#define __indr_reference(sym,alias) __lint_equal__(sym,alias)
+#define __warn_references(sym,msg)
+#define __weak_alias(alias,sym) __lint_equal__(sym,alias)
+#elif defined(__GNUC__) && defined(__STDC__)
+#define __weak_alias(alias,sym) \
+ __asm__(".weak " __STRING(alias) " ; " __STRING(alias) \
+ " = " __STRING(sym))
+#define __warn_references(sym,msg) \
+ __asm__(".section .gnu.warning." __STRING(sym) \
+ " ; .ascii \"" msg "\" ; .text")
+#endif
+
+#endif /* !_SH_CDEFS_H_ */
diff --git a/sys/arch/sh/include/clock.h b/sys/arch/sh/include/clock.h
new file mode 100644
index 00000000000..80a3167b639
--- /dev/null
+++ b/sys/arch/sh/include/clock.h
@@ -0,0 +1,90 @@
+/* $OpenBSD: clock.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: clock.h,v 1.2 2002/04/28 17:10:33 uch Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+/*
+ * void sh_clock_init(int flags, struct rtc_ops *):
+ * flags:
+ * SH_CLOCK_NORTC ... If SH RTC module is disabled, set this.
+ * internal module don't use RTCCLK.
+ * SH_CLOCK_NOINITTODR ... Don't initialize RTC time.
+ * rtc_ops:
+ * Machine dependent RTC ops pointer. If NULL is specified, use SH
+ * internal RTC.
+ *
+ * void machine_clock_init(void):
+ * Implement machine specific part of clock routines.
+ * must call sh_clock_init() at exit.
+ *
+ * int sh_clock_get_cpuclock(void):
+ * returns CPU clock estimated by sh_clock_init().
+ *
+ * int sh_clock_get_pclock(void):
+ * returns PCLOCK. when PCLOCK is not specified by kernel configuration
+ * file, this value is estimated by sh_clock_init().
+ *
+ */
+struct rtc_ops;
+struct clock_ymdhms;
+
+void sh_clock_init(int, struct rtc_ops *);
+#define SH_CLOCK_NORTC 0x00000001
+#define SH_CLOCK_NOINITTODR 0x00000002
+void machine_clock_init(void);
+
+int sh_clock_get_cpuclock(void);
+int sh_clock_get_pclock(void);
+
+/*
+ * SH RTC module interface.
+ */
+void sh_rtc_init(void *);
+void sh_rtc_get(void *, time_t, struct clock_ymdhms *);
+void sh_rtc_set(void *, struct clock_ymdhms *);
+
+/*
+ * machine specific RTC ops
+ */
+struct clock_ymdhms;
+struct rtc_ops {
+ void *_cookie;
+ void (*init)(void *);
+ void (*get)(void *, time_t, struct clock_ymdhms *);
+ void (*set)(void *, struct clock_ymdhms *);
+};
+
diff --git a/sys/arch/sh/include/cpgreg.h b/sys/arch/sh/include/cpgreg.h
new file mode 100644
index 00000000000..2e7d5694295
--- /dev/null
+++ b/sys/arch/sh/include/cpgreg.h
@@ -0,0 +1,48 @@
+/* $OpenBSD: cpgreg.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: cpgreg.h,v 1.5 2002/04/28 17:10:34 uch Exp $ */
+
+/*-
+ * Copyright (C) 1999 SAITOH Masanobu. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SH_CPGREG_H_
+#define _SH_CPGREG_H_
+
+/*
+ * Clock Pulse Generator
+ */
+#define SH3_FRQCR 0xffffff80 /* 16bit */
+#define SH4_FRQCR 0xffc00000 /* 16bit */
+
+/*
+ * Standby Control
+ */
+#define SH3_STBCR 0xffffff82 /* 8bit */
+#define SH7709_STBCR2 0xffffff88 /* 8bit */
+
+#define SH4_STBCR 0xffc00004 /* 8bit */
+#define SH4_STBCR2 0xffc00010 /* 8bit */
+
+#endif /* !_SH_CPGREG_H_ */
diff --git a/sys/arch/sh/include/cpu.h b/sys/arch/sh/include/cpu.h
new file mode 100644
index 00000000000..682ab233eaa
--- /dev/null
+++ b/sys/arch/sh/include/cpu.h
@@ -0,0 +1,213 @@
+/* $OpenBSD: cpu.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: cpu.h,v 1.41 2006/01/21 04:24:12 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)cpu.h 5.4 (Berkeley) 5/9/91
+ */
+
+/*
+ * SH3/SH4 support.
+ *
+ * T.Horiuchi Brains Corp. 5/22/98
+ */
+
+#ifndef _SH_CPU_H_
+#define _SH_CPU_H_
+
+#include <sh/psl.h>
+#include <sh/frame.h>
+
+#ifdef _KERNEL
+
+/*
+ * Can't swapout u-area, (__SWAP_BROKEN)
+ * since we use P1 converted address for trapframe.
+ */
+#define cpu_swapin(p) /* nothing */
+#define cpu_swapout(p) /* nothing */
+
+/*
+ * Arguments to hardclock and gatherstats encapsulate the previous
+ * machine state in an opaque clockframe.
+ */
+struct clockframe {
+ int spc; /* program counter at time of interrupt */
+ int ssr; /* status register at time of interrupt */
+ int ssp; /* stack pointer at time of interrupt */
+};
+
+#define CLKF_USERMODE(cf) (!KERNELMODE((cf)->ssr))
+#define CLKF_BASEPRI(cf) (((cf)->ssr & 0xf0) == 0)
+#define CLKF_PC(cf) ((cf)->spc)
+#define CLKF_INTR(cf) 0 /* XXX */
+
+/*
+ * This is used during profiling to integrate system time. It can safely
+ * assume that the process is resident.
+ */
+#define PROC_PC(p) \
+ (((struct trapframe *)(p)->p_md.md_regs)->tf_spc)
+
+/*
+ * Preempt the current process if in interrupt from user mode,
+ * or after the current trap/syscall if in system mode.
+ */
+#define need_resched(ci) \
+do { \
+ want_resched = 1; \
+ if (curproc != NULL) \
+ aston(curproc); \
+} while (/*CONSTCOND*/0)
+
+/*
+ * Give a profiling tick to the current process when the user profiling
+ * buffer pages are invalid. On the MIPS, request an ast to send us
+ * through trap, marking the proc as needing a profiling tick.
+ */
+#define need_proftick(p) \
+do { \
+ (p)->p_flag |= P_OWEUPC; \
+ aston(p); \
+} while (/*CONSTCOND*/0)
+
+/*
+ * Notify the current process (p) that it has a signal pending,
+ * process as soon as possible.
+ */
+#define signotify(p) aston(p)
+
+#define aston(p) ((p)->p_md.md_astpending = 1)
+
+extern int want_resched; /* need_resched() was called */
+
+/*
+ * We need a machine-independent name for this.
+ */
+#define DELAY(x) delay(x)
+#endif /* _KERNEL */
+
+/*
+ * Logical address space of SH3/SH4 CPU.
+ */
+#define SH3_PHYS_MASK 0x1fffffff
+
+#define SH3_P0SEG_BASE 0x00000000 /* TLB mapped, also U0SEG */
+#define SH3_P0SEG_END 0x7fffffff
+#define SH3_P1SEG_BASE 0x80000000 /* pa == va */
+#define SH3_P1SEG_END 0x9fffffff
+#define SH3_P2SEG_BASE 0xa0000000 /* pa == va, non-cacheable */
+#define SH3_P2SEG_END 0xbfffffff
+#define SH3_P3SEG_BASE 0xc0000000 /* TLB mapped, kernel mode */
+#define SH3_P3SEG_END 0xdfffffff
+#define SH3_P4SEG_BASE 0xe0000000 /* peripheral space */
+#define SH3_P4SEG_END 0xffffffff
+
+#define SH3_P1SEG_TO_PHYS(x) ((uint32_t)(x) & SH3_PHYS_MASK)
+#define SH3_P2SEG_TO_PHYS(x) ((uint32_t)(x) & SH3_PHYS_MASK)
+#define SH3_PHYS_TO_P1SEG(x) ((uint32_t)(x) | SH3_P1SEG_BASE)
+#define SH3_PHYS_TO_P2SEG(x) ((uint32_t)(x) | SH3_P2SEG_BASE)
+#define SH3_P1SEG_TO_P2SEG(x) ((uint32_t)(x) | 0x20000000)
+#define SH3_P2SEG_TO_P1SEG(x) ((uint32_t)(x) & ~0x20000000)
+
+#ifdef _KERNEL
+#ifndef __lint__
+
+/* switch from P1 to P2 */
+#define RUN_P2 do { \
+ void *p; \
+ p = &&P2; \
+ goto *(void *)SH3_P1SEG_TO_P2SEG(p); \
+ P2: (void)0; \
+ } while (0)
+
+/* switch from P2 to P1 */
+#define RUN_P1 do { \
+ void *p; \
+ p = &&P1; \
+ __asm volatile("nop;nop;nop;nop;nop;nop;nop;nop"); \
+ goto *(void *)SH3_P2SEG_TO_P1SEG(p); \
+ P1: (void)0; \
+ } while (0)
+
+#else /* __lint__ */
+#define RUN_P2 do {} while (/* CONSTCOND */ 0)
+#define RUN_P1 do {} while (/* CONSTCOND */ 0)
+#endif
+#endif
+
+#if defined(SH4)
+/* SH4 Processor Version Register */
+#define SH4_PVR_ADDR 0xff000030 /* P4 address */
+#define SH4_PVR (*(volatile uint32_t *) SH4_PVR_ADDR)
+#define SH4_PRR_ADDR 0xff000044 /* P4 address */
+#define SH4_PRR (*(volatile uint32_t *) SH4_PRR_ADDR)
+
+#define SH4_PVR_MASK 0xffffff00
+#define SH4_PVR_SH7750 0x04020500 /* SH7750 */
+#define SH4_PVR_SH7750S 0x04020600 /* SH7750S */
+#define SH4_PVR_SH775xR 0x04050000 /* SH775xR */
+#define SH4_PVR_SH7751 0x04110000 /* SH7751 */
+
+#define SH4_PRR_MASK 0xfffffff0
+#define SH4_PRR_7750R 0x00000100 /* SH7750R */
+#define SH4_PRR_7751R 0x00000110 /* SH7751R */
+#endif
+
+/*
+ * pull in #defines for kinds of processors
+ */
+#include <machine/cputypes.h>
+
+/*
+ * CTL_MACHDEP definitions.
+ */
+#define CPU_CONSDEV 1 /* dev_t: console terminal device */
+#define CPU_MAXID 2 /* number of valid machdep ids */
+
+#define CTL_MACHDEP_NAMES { \
+ { 0, 0 }, \
+ { "console_device", CTLTYPE_STRUCT }, \
+}
+
+#ifdef _KERNEL
+void sh_cpu_init(int, int);
+void sh_startup(void);
+__dead void cpu_reset(void); /* soft reset */
+void _cpu_spin(uint32_t); /* for delay loop. */
+void delay(int);
+struct pcb;
+void savectx(struct pcb *);
+void dumpsys(void);
+#endif /* _KERNEL */
+#endif /* !_SH_CPU_H_ */
diff --git a/sys/arch/sh/include/cputypes.h b/sys/arch/sh/include/cputypes.h
new file mode 100644
index 00000000000..5befc6321c6
--- /dev/null
+++ b/sys/arch/sh/include/cputypes.h
@@ -0,0 +1,79 @@
+/* $OpenBSD: cputypes.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: cputypes.h,v 1.10 2006/01/21 00:40:36 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ */
+
+#ifndef _SH_CPUTYPES_H_
+#define _SH_CPUTYPES_H_
+
+#ifdef _KERNEL
+
+#define CPU_ARCH_SH3 3
+#define CPU_ARCH_SH4 4
+
+/* SH3 series */
+#define CPU_PRODUCT_7708 1
+#define CPU_PRODUCT_7708S 2
+#define CPU_PRODUCT_7708R 3
+#define CPU_PRODUCT_7709 4
+#define CPU_PRODUCT_7709A 5
+
+/* SH4 series */
+#define CPU_PRODUCT_7750 6
+#define CPU_PRODUCT_7750S 7
+#define CPU_PRODUCT_7750R 8
+#define CPU_PRODUCT_7751 9
+#define CPU_PRODUCT_7751R 10
+
+
+#ifndef _LOCORE
+extern int cpu_arch;
+extern int cpu_product;
+#if defined(SH3) && defined(SH4)
+#define CPU_IS_SH3 (cpu_arch == CPU_ARCH_SH3)
+#define CPU_IS_SH4 (cpu_arch == CPU_ARCH_SH4)
+#elif defined(SH3)
+#define CPU_IS_SH3 (/* CONSTCOND */1)
+#define CPU_IS_SH4 (/* CONSTCOND */0)
+#elif defined(SH4)
+#define CPU_IS_SH3 (/* CONSTCOND */0)
+#define CPU_IS_SH4 (/* CONSTCOND */1)
+#else
+#error "define SH3 and/or SH4"
+#endif
+#endif /* !_LOCORE */
+
+#endif /* _KERNEL */
+
+#endif /* !_SH_CPUTYPES_H_ */
diff --git a/sys/arch/sh/include/db_machdep.h b/sys/arch/sh/include/db_machdep.h
new file mode 100644
index 00000000000..10afa9cf335
--- /dev/null
+++ b/sys/arch/sh/include/db_machdep.h
@@ -0,0 +1,83 @@
+/* $OpenBSD: db_machdep.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: db_machdep.h,v 1.12 2006/05/10 06:24:03 skrll Exp $ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#ifndef _SH_DB_MACHDEP_H_
+#define _SH_DB_MACHDEP_H_
+
+/*
+ * Machine-dependent defines for the kernel debugger.
+ */
+
+#include <sys/param.h>
+#include <uvm/uvm_extern.h>
+#include <sh/trap.h>
+
+typedef vaddr_t db_addr_t; /* address - unsigned */
+typedef long db_expr_t; /* expression - signed */
+
+typedef struct trapframe db_regs_t;
+extern db_regs_t ddb_regs; /* register state */
+#define DDB_REGS (&ddb_regs)
+
+#define PC_REGS(regs) ((db_addr_t)(regs)->tf_spc)
+#define PC_ADVANCE(regs) ((regs)->tf_spc += BKPT_SIZE)
+
+#define BKPT_INST 0xc3c3 /* breakpoint instruction */
+#define BKPT_SIZE 2 /* size of breakpoint inst */
+#define BKPT_SET(inst) BKPT_INST
+
+#define FIXUP_PC_AFTER_BREAK(regs) ((regs)->tf_spc -= BKPT_SIZE)
+
+#define IS_BREAKPOINT_TRAP(type, code) ((type) == EXPEVT_BREAK)
+#define IS_WATCHPOINT_TRAP(type, code) (0) /* XXX (msaitoh) */
+
+#define inst_load(ins) 0
+#define inst_store(ins) 0
+
+/* macro for checking if a thread has used floating-point */
+#define db_thread_fp_used(thread) ((thread)->pcb->ims.ifps != 0)
+
+int kdb_trap(int, int, db_regs_t *);
+boolean_t inst_call(int);
+boolean_t inst_return(int);
+boolean_t inst_trap_return(int);
+
+/*
+ * We use ELF symbols in DDB.
+ *
+ */
+#define DB_ELF_SYMBOLS
+#define DB_ELFSIZE 32
+
+/*
+ * We have machine-dependent commands.
+ */
+#define DB_MACHINE_COMMANDS
+
+#endif /* !_SH_DB_MACHDEP_H_ */
diff --git a/sys/arch/sh/include/devreg.h b/sys/arch/sh/include/devreg.h
new file mode 100644
index 00000000000..37886f04a7b
--- /dev/null
+++ b/sys/arch/sh/include/devreg.h
@@ -0,0 +1,83 @@
+/* $OpenBSD: devreg.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: devreg.h,v 1.5 2006/01/21 04:57:07 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ */
+
+#ifndef _SH_DEVREG_H_
+#define _SH_DEVREG_H_
+/*
+ * SH embeded device register defines.
+ */
+
+/*
+ * Access method
+ */
+#define _reg_read_1(a) (*(volatile uint8_t *)((vaddr_t)(a)))
+#define _reg_read_2(a) (*(volatile uint16_t *)((vaddr_t)(a)))
+#define _reg_read_4(a) (*(volatile uint32_t *)((vaddr_t)(a)))
+#define _reg_write_1(a, v) \
+ (*(volatile uint8_t *)(a) = (uint8_t)(v))
+#define _reg_write_2(a, v) \
+ (*(volatile uint16_t *)(a) = (uint16_t)(v))
+#define _reg_write_4(a, v) \
+ (*(volatile uint32_t *)(a) = (uint32_t)(v))
+#define _reg_bset_1(a, v) \
+ (*(volatile uint8_t *)(a) |= (uint8_t)(v))
+#define _reg_bset_2(a, v) \
+ (*(volatile uint16_t *)(a) |= (uint16_t)(v))
+#define _reg_bset_4(a, v) \
+ (*(volatile uint32_t *)(a) |= (uint32_t)(v))
+#define _reg_bclr_1(a, v) \
+ (*(volatile uint8_t *)(a) &= ~(uint8_t)(v))
+#define _reg_bclr_2(a, v) \
+ (*(volatile uint16_t *)(a) &= ~(uint16_t)(v))
+#define _reg_bclr_4(a, v) \
+ (*(volatile uint32_t *)(a) &= ~(uint32_t)(v))
+
+/*
+ * Register address.
+ */
+#if defined(SH3) && defined(SH4)
+#define SH_(x) __sh_ ## x
+#elif defined(SH3)
+#define SH_(x) SH3_ ## x
+#elif defined(SH4)
+#define SH_(x) SH4_ ## x
+#endif
+
+#ifndef _LOCORE
+/* Initialize register address for SH3 && SH4 kernel. */
+void sh_devreg_init(void);
+#endif
+#endif /* !_SH_DEVREG_H_ */
diff --git a/sys/arch/sh/include/disklabel.h b/sys/arch/sh/include/disklabel.h
new file mode 100644
index 00000000000..0b61abbc41a
--- /dev/null
+++ b/sys/arch/sh/include/disklabel.h
@@ -0,0 +1,112 @@
+/* $OpenBSD: disklabel.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: disklabel.h,v 1.2 2001/11/25 19:02:03 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1994 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * disklabel.h
+ *
+ * machine specific disk label info
+ *
+ * Created : 04/10/94
+ */
+
+#ifndef _ARM_DISKLABEL_H_
+#define _ARM_DISKLABEL_H_
+
+#define LABELSECTOR 1 /* sector containing label */
+#define LABELOFFSET 0 /* offset of label in sector */
+#define MAXPARTITIONS 16 /* number of partitions */
+#define RAW_PART 2 /* raw partition: XX?c */
+
+#include <sys/dkbad.h>
+#if 0
+#include <arm/disklabel_acorn.h>
+#include <sys/disklabel_mbr.h>
+#endif
+
+/* MBR partition table */
+#define DOSBBSECTOR 0 /* MBR sector number */
+#define DOSPARTOFF 446 /* Offset of MBR partition table */
+#define NDOSPART 4 /* # of partitions in MBR */
+#define DOSMAGICOFF 510 /* Offset of magic number */
+#define DOSMAGIC 0xaa55 /* Actual magic number */
+#define MBRMAGIC DOSMAGIC
+#define DOSMBR_SIGNATURE MBRMAGIC
+#define DOSMBR_SIGNATURE_OFF DOSMAGICOFF
+#define DOSACTIVE 0x80
+
+
+struct dos_partition {
+ u_int8_t dp_flag; /* bootstrap flags */
+ u_int8_t dp_shd; /* starting head */
+ u_int8_t dp_ssect; /* starting sector */
+ u_int8_t dp_scyl; /* starting cylinder */
+ u_int8_t dp_typ; /* partition type (see below) */
+ u_int8_t dp_ehd; /* end head */
+ u_int8_t dp_esect; /* end sector */
+ u_int8_t dp_ecyl; /* end cylinder */
+ u_int32_t dp_start; /* absolute starting sector number */
+ u_int32_t dp_size; /* partition size in sectors */
+};
+
+/* Known DOS partition types. */
+#define DOSPTYP_UNUSED 0x00 /* Unused partition */
+#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
+#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
+#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
+#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
+#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
+#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
+#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
+#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
+#define DOSPTYP_ONTRACK 0x54
+#define DOSPTYP_LINUX 0x83 /* That other thing */
+#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
+#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
+#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
+
+/* Isolate the relevant bits to get sector and cylinder. */
+#define DPSECT(s) ((s) & 0x3f)
+#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
+
+
+struct cpu_disklabel {
+ struct dos_partition dosparts[NDOSPART];
+ struct dkbad bad;
+};
+
+#endif /* _ARM_DISKLABEL_H_ */
diff --git a/sys/arch/sh/include/endian.h b/sys/arch/sh/include/endian.h
new file mode 100644
index 00000000000..9615f567cd1
--- /dev/null
+++ b/sys/arch/sh/include/endian.h
@@ -0,0 +1,43 @@
+/* $OpenBSD: endian.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: endian.h,v 1.4 2000/03/17 00:09:25 mycroft Exp $ */
+
+/* Written by Manuel Bouyer. Public domain */
+
+#ifndef _SH_ENDIAN_H_
+#define _SH_ENDIAN_H_
+
+#ifdef __GNUC__
+
+#define __swap64md __swap64gen
+
+#define __swap16md(x) ({ \
+ uint16_t rval; \
+ \
+ __asm volatile ("swap.b %1,%0" : "=r"(rval) : "r"(x)); \
+ \
+ rval; \
+})
+
+#define __swap32md(x) ({ \
+ uint32_t rval; \
+ \
+ __asm volatile ("swap.b %1,%0; swap.w %0,%0; swap.b %0,%0" \
+ : "=r"(rval) : "r"(x)); \
+ \
+ rval; \
+})
+
+#define MD_SWAP
+
+#endif /* __GNUC_ */
+
+#ifdef __LITTLE_ENDIAN__
+#define _BYTE_ORDER _LITTLE_ENDIAN
+#else
+#define _BYTE_ORDER _BIG_ENDIAN
+#endif
+#include <sys/endian.h>
+
+#define __STRICT_ALIGNMENT
+
+#endif /* !_SH_ENDIAN_H_ */
diff --git a/sys/arch/sh/include/exec.h b/sys/arch/sh/include/exec.h
new file mode 100644
index 00000000000..2bf1c48d8ae
--- /dev/null
+++ b/sys/arch/sh/include/exec.h
@@ -0,0 +1,70 @@
+/* $OpenBSD: exec.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: elf_machdep.h,v 1.8 2002/04/28 17:10:34 uch Exp $ */
+
+#define __LDPGSZ 4096
+
+#define NATIVE_EXEC_ELF
+
+#define ARCH_ELFSIZE 32 /* MD native binary size */
+#define ELF_TARG_CLASS ELFCLASS32
+#ifdef __LITTLE_ENDIAN__
+#define ELF_TARG_DATA ELFDATA2LSB
+#else
+#define ELF_TARG_DATA ELFDATA2MSB
+#endif
+#define ELF_TARG_MACH EM_SH
+
+#define _KERN_DO_ELF
+#define _NLIST_DO_ELF
+
+/*
+ * SuperH ELF header flags.
+ */
+#define EF_SH_MACH_MASK 0x1f
+
+#define EF_SH_UNKNOWN 0x00
+#define EF_SH_SH1 0x01
+#define EF_SH_SH2 0x02
+#define EF_SH_SH3 0x03
+#define EF_SH_DSP 0x04
+#define EF_SH_SH3_DSP 0x05
+#define EF_SH_SH3E 0x08
+#define EF_SH_SH4 0x09
+
+#define EF_SH_HAS_DSP(x) ((x) & EF_SH_DSP)
+#define EF_SH_HAS_FP(x) ((x) & EF_SH_SH3E)
+
+
+#define R_SH_NONE 0
+#define R_SH_DIR32 1
+#define R_SH_REL32 2
+#define R_SH_DIR8WPN 3
+#define R_SH_IND12W 4
+#define R_SH_DIR8WPL 5
+#define R_SH_DIR8WPZ 6
+#define R_SH_DIR8BP 7
+#define R_SH_DIR8W 8
+#define R_SH_DIR8L 9
+#define R_SH_SWITCH16 25
+#define R_SH_SWITCH32 26
+#define R_SH_USES 27
+#define R_SH_COUNT 28
+#define R_SH_ALIGN 29
+#define R_SH_CODE 30
+#define R_SH_DATA 31
+#define R_SH_LABEL 32
+#define R_SH_SWITCH8 33
+#define R_SH_GNU_VTINHERIT 34
+#define R_SH_GNU_VTENTRY 35
+#define R_SH_LOOP_START 36
+#define R_SH_LOOP_END 37
+#define R_SH_GOT32 160
+#define R_SH_PLT32 161
+#define R_SH_COPY 162
+#define R_SH_GLOB_DAT 163
+#define R_SH_JMP_SLOT 164
+#define R_SH_RELATIVE 165
+#define R_SH_GOTOFF 166
+#define R_SH_GOTPC 167
+
+#define R_TYPE(name) __CONCAT(R_SH_,name)
diff --git a/sys/arch/sh/include/float.h b/sys/arch/sh/include/float.h
new file mode 100644
index 00000000000..b39dd8fe6ff
--- /dev/null
+++ b/sys/arch/sh/include/float.h
@@ -0,0 +1,76 @@
+/* $OpenBSD: float.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)float.h 7.1 (Berkeley) 5/8/90
+ */
+
+#ifndef _SH_FLOAT_H_
+#define _SH_FLOAT_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int __flt_rounds(void);
+__END_DECLS
+
+#define FLT_RADIX 2 /* b */
+#define FLT_ROUNDS __flt_rounds()
+
+#define FLT_MANT_DIG 24 /* p */
+#define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */
+#define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */
+#define FLT_MIN_EXP (-125) /* emin */
+#define FLT_MIN 1.17549435E-38F /* b**(emin-1) */
+#define FLT_MIN_10_EXP (-37) /* ceil(log10(b**(emin-1))) */
+#define FLT_MAX_EXP 128 /* emax */
+#define FLT_MAX 3.40282347E+38F /* (1-b**(-p))*b**emax */
+#define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */
+
+#define DBL_MANT_DIG 53
+#define DBL_EPSILON 2.2204460492503131E-16
+#define DBL_DIG 15
+#define DBL_MIN_EXP (-1021)
+#define DBL_MIN 2.2250738585072014E-308
+#define DBL_MIN_10_EXP (-307)
+#define DBL_MAX_EXP 1024
+#define DBL_MAX 1.7976931348623157E+308
+#define DBL_MAX_10_EXP 308
+
+#define LDBL_MANT_DIG DBL_MANT_DIG
+#define LDBL_EPSILON DBL_EPSILON
+#define LDBL_DIG DBL_DIG
+#define LDBL_MIN_EXP DBL_MIN_EXP
+#define LDBL_MIN DBL_MIN
+#define LDBL_MIN_10_EXP DBL_MIN_10_EXP
+#define LDBL_MAX_EXP DBL_MAX_EXP
+#define LDBL_MAX DBL_MAX
+#define LDBL_MAX_10_EXP DBL_MAX_10_EXP
+
+#endif /* _SH_FLOAT_H_ */
diff --git a/sys/arch/sh/include/frame.h b/sys/arch/sh/include/frame.h
new file mode 100644
index 00000000000..fd7176d829a
--- /dev/null
+++ b/sys/arch/sh/include/frame.h
@@ -0,0 +1,130 @@
+/* $OpenBSD: frame.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: frame.h,v 1.14 2005/12/11 12:18:58 christos Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)frame.h 5.2 (Berkeley) 1/18/91
+ */
+
+/*-
+ * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)frame.h 5.2 (Berkeley) 1/18/91
+ */
+
+#ifndef _SH_FRAME_H_
+#define _SH_FRAME_H_
+
+#include <sys/signal.h>
+
+/*
+ * Exception Stack Frame
+ */
+struct trapframe {
+ /* software member */
+ int tf_expevt;
+ int tf_ubc;
+ /* hardware registers */
+ int tf_spc;
+ int tf_ssr;
+ int tf_macl;
+ int tf_mach;
+ int tf_pr;
+ int tf_r13;
+ int tf_r12;
+ int tf_r11;
+ int tf_r10;
+ int tf_r9;
+ int tf_r8;
+ int tf_r7;
+ int tf_r6;
+ int tf_r5;
+ int tf_r4;
+ int tf_r3;
+ int tf_r2;
+ int tf_r1;
+ int tf_r0;
+ int tf_r15;
+ int tf_r14;
+};
+
+/*
+ * Stack frame inside cpu_switch()
+ */
+struct switchframe {
+ int sf_r15;
+ int sf_r14;
+ int sf_r13;
+ int sf_r12;
+ int sf_r11;
+ int sf_r10;
+ int sf_r9;
+ int sf_r8;
+ int sf_pr;
+ int sf_r6_bank;
+ int sf_sr;
+ int sf_r7_bank;
+};
+
+#endif /* !_SH_FRAME_H_ */
diff --git a/sys/arch/sh/include/ieee.h b/sys/arch/sh/include/ieee.h
new file mode 100644
index 00000000000..7ee46d82db4
--- /dev/null
+++ b/sys/arch/sh/include/ieee.h
@@ -0,0 +1,132 @@
+/* $OpenBSD: ieee.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ieee.h 8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * ieee.h defines the machine-dependent layout of the machine's IEEE
+ * floating point. It does *not* define (yet?) any of the rounding
+ * mode bits, exceptions, and so forth.
+ */
+
+/*
+ * Define the number of bits in each fraction and exponent.
+ *
+ * k k+1
+ * Note that 1.0 x 2 == 0.1 x 2 and that denorms are represented
+ *
+ * (-exp_bias+1)
+ * as fractions that look like 0.fffff x 2 . This means that
+ *
+ * -126
+ * the number 0.10000 x 2 , for instance, is the same as the normalized
+ *
+ * -127 -128
+ * float 1.0 x 2 . Thus, to represent 2 , we need one leading zero
+ *
+ * -129
+ * in the fraction; to represent 2 , we need two, and so on. This
+ *
+ * (-exp_bias-fracbits+1)
+ * implies that the smallest denormalized number is 2
+ *
+ * for whichever format we are talking about: for single precision, for
+ *
+ * -126 -149
+ * instance, we get .00000000000000000000001 x 2 , or 1.0 x 2 , and
+ *
+ * -149 == -127 - 23 + 1.
+ */
+#define SNG_EXPBITS 8
+#define SNG_FRACBITS 23
+
+#define DBL_EXPBITS 11
+#define DBL_FRACBITS 52
+
+#define EXT_EXPBITS 15
+#define EXT_FRACBITS 112
+
+struct ieee_single {
+ u_int sng_sign:1;
+ u_int sng_exp:8;
+ u_int sng_frac:23;
+};
+
+struct ieee_double {
+ u_int dbl_sign:1;
+ u_int dbl_exp:11;
+ u_int dbl_frach:20;
+ u_int dbl_fracl;
+};
+
+struct ieee_ext {
+ u_int ext_sign:1;
+ u_int ext_exp:15;
+ u_int ext_frach:16;
+ u_int ext_frachm;
+ u_int ext_fraclm;
+ u_int ext_fracl;
+};
+
+/*
+ * Floats whose exponent is in [1..INFNAN) (of whatever type) are
+ * `normal'. Floats whose exponent is INFNAN are either Inf or NaN.
+ * Floats whose exponent is zero are either zero (iff all fraction
+ * bits are zero) or subnormal values.
+ *
+ * A NaN is a `signalling NaN' if its QUIETNAN bit is clear in its
+ * high fraction; if the bit is set, it is a `quiet NaN'.
+ */
+#define SNG_EXP_INFNAN 255
+#define DBL_EXP_INFNAN 2047
+#define EXT_EXP_INFNAN 32767
+
+#if 0
+#define SNG_QUIETNAN (1 << 22)
+#define DBL_QUIETNAN (1 << 19)
+#define EXT_QUIETNAN (1 << 15)
+#endif
+
+/*
+ * Exponent biases.
+ */
+#define SNG_EXP_BIAS 127
+#define DBL_EXP_BIAS 1023
+#define EXT_EXP_BIAS 16383
diff --git a/sys/arch/sh/include/ieeefp.h b/sys/arch/sh/include/ieeefp.h
new file mode 100644
index 00000000000..141048038ad
--- /dev/null
+++ b/sys/arch/sh/include/ieeefp.h
@@ -0,0 +1,27 @@
+/* $OpenBSD: ieeefp.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: ieeefp.h,v 1.3 2002/04/28 17:10:34 uch Exp $ */
+
+/*
+ * Written by J.T. Conklin, Apr 6, 1995
+ * Public domain.
+ */
+
+#ifndef _SH_IEEEFP_H_
+#define _SH_IEEEFP_H_
+
+typedef int fp_except;
+#define FP_X_INV 0x01 /* invalid operation exception */
+#define FP_X_DNML 0x02 /* denormalization exception */
+#define FP_X_DZ 0x04 /* divide-by-zero exception */
+#define FP_X_OFL 0x08 /* overflow exception */
+#define FP_X_UFL 0x10 /* underflow exception */
+#define FP_X_IMP 0x20 /* imprecise (loss of precision) */
+
+typedef enum {
+ FP_RN=0, /* round to nearest representable number */
+ FP_RM=1, /* round toward negative infinity */
+ FP_RP=2, /* round toward positive infinity */
+ FP_RZ=3 /* round to zero (truncate) */
+} fp_rnd;
+
+#endif /* !_SH_IEEEFP_H_ */
diff --git a/sys/arch/sh/include/intcreg.h b/sys/arch/sh/include/intcreg.h
new file mode 100644
index 00000000000..e69f31db7aa
--- /dev/null
+++ b/sys/arch/sh/include/intcreg.h
@@ -0,0 +1,127 @@
+/* $OpenBSD: intcreg.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: intcreg.h,v 1.10 2005/12/11 12:18:58 christos Exp $ */
+
+/*-
+ * Copyright (C) 1999 SAITOH Masanobu. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SH_INTCREG_H_
+#define _SH_INTCREG_H_
+#include <sh/devreg.h>
+
+/*
+ * INTC
+ */
+/* SH3 SH7708*, SH7709* common */
+#define SH3_ICR0 0xfffffee0 /* 16bit */
+#define SH3_IPRA 0xfffffee2 /* 16bit */
+#define SH3_IPRB 0xfffffee4 /* 16bit */
+
+/* SH7709, SH7709A only */
+#define SH7709_ICR1 0xa4000010 /* 16bit */
+#define SH7709_ICR2 0xa4000012 /* 16bit */
+#define SH7709_PINTER 0xa4000014 /* 16bit */
+#define SH7709_IPRC 0xa4000016 /* 16bit */
+#define SH7709_IPRD 0xa4000018 /* 16bit */
+#define SH7709_IPRE 0xa400001a /* 16bit */
+#define SH7709_IRR0 0xa4000004 /* 8bit */
+#define SH7709_IRR1 0xa4000006 /* 8bit */
+#define SH7709_IRR2 0xa4000008 /* 8bit */
+
+#define IPRC_IRQ3_MASK 0xf000
+#define IPRC_IRQ2_MASK 0x0f00
+#define IPRC_IRQ1_MASK 0x00f0
+#define IPRC_IRQ0_MASK 0x000f
+
+#define IPRD_PINT07_MASK 0xf000
+#define IPRD_PINT8F_MASK 0x0f00
+#define IPRD_IRQ5_MASK 0x00f0
+#define IPRD_IRQ4_MASK 0x000f
+
+#define IPRE_DMAC_MASK 0xf000
+#define IPRE_IRDA_MASK 0x0f00
+#define IPRE_SCIF_MASK 0x00f0
+#define IPRE_ADC_MASK 0x000f
+
+#define IRR0_PINT8F 0x80
+#define IRR0_PINT07 0x40
+#define IRR0_IRQ5 0x20
+#define IRR0_IRQ4 0x10
+#define IRR0_IRQ3 0x08
+#define IRR0_IRQ2 0x04
+#define IRR0_IRQ1 0x02
+#define IRR0_IRQ0 0x01
+
+
+/* SH4 */
+#define SH4_ICR 0xffd00000 /* 16bit */
+#define SH4_IPRA 0xffd00004 /* 16bit */
+#define SH4_IPRB 0xffd00008 /* 16bit */
+#define SH4_IPRC 0xffd0000c /* 16bit */
+#define SH4_IPRD 0xffd00010 /* 16bit */
+#define SH4_INTPRI00 0xfe080000 /* 32bit */
+#define SH4_INTREQ00 0xfe080020 /* 32bit */
+#define SH4_INTMSK00 0xfe080040 /* 32bit */
+#define SH4_INTMSKCLR00 0xfe080060 /* 32bit */
+
+#define IPRC_GPIO_MASK 0xf000
+#define IPRC_DMAC_MASK 0x0f00
+#define IPRC_SCIF_MASK 0x00f0
+#define IPRC_HUDI_MASK 0x000f
+
+#define IPRD_IRL0_MASK 0xf000
+#define IPRD_IRL1_MASK 0x0f00
+#define IPRD_IRL2_MASK 0x00f0
+#define IPRD_IRL3_MASK 0x000f
+
+#define IPRA_TMU0_MASK 0xf000
+#define IPRA_TMU1_MASK 0x0f00
+#define IPRA_TMU2_MASK 0x00f0
+#define IPRA_RTC_MASK 0x000f
+
+#define IPRB_WDT_MASK 0xf000
+#define IPRB_REF_MASK 0x0f00
+#define IPRB_SCI_MASK 0x00f0
+
+#define INTPRI00_PCI0_MASK 0x0000000f
+#define INTPRI00_PCI1_MASK 0x000000f0
+#define INTPRI00_TMU3_MASK 0x00000f00
+#define INTPRI00_TMU4_MASK 0x0000f000
+
+/* INTREQ/INTMSK/INTMSKCLR */
+#define INTREQ00_PCISERR 0x00000001
+#define INTREQ00_PCIDMA3 0x00000002
+#define INTREQ00_PCIDMA2 0x00000004
+#define INTREQ00_PCIDMA1 0x00000008
+#define INTREQ00_PCIDMA0 0x00000010
+#define INTREQ00_PCIPWON 0x00000020
+#define INTREQ00_PCIPWDWN 0x00000040
+#define INTREQ00_PCIERR 0x00000080
+#define INTREQ00_TUNI3 0x00000100
+#define INTREQ00_TUNI4 0x00000200
+
+#define INTMSK00_MASK_ALL 0x000003ff
+
+#endif /* !_SH_INTCREG_H_ */
diff --git a/sys/arch/sh/include/internal_types.h b/sys/arch/sh/include/internal_types.h
new file mode 100644
index 00000000000..1c6d5a40911
--- /dev/null
+++ b/sys/arch/sh/include/internal_types.h
@@ -0,0 +1,6 @@
+/* $OpenBSD: internal_types.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* Public domain */
+#ifndef _SH_INTERNAL_TYPES_H_
+#define _SH_INTERNAL_TYPES_H_
+
+#endif
diff --git a/sys/arch/sh/include/intr.h b/sys/arch/sh/include/intr.h
new file mode 100644
index 00000000000..eabf78662ad
--- /dev/null
+++ b/sys/arch/sh/include/intr.h
@@ -0,0 +1,145 @@
+/* $OpenBSD: intr.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: intr.h,v 1.22 2006/01/24 23:51:42 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ */
+
+#ifndef _SH_INTR_H_
+#define _SH_INTR_H_
+
+#ifdef _KERNEL
+
+#include <sys/device.h>
+#include <sys/evcount.h>
+#include <sys/lock.h>
+#include <sys/queue.h>
+#include <sh/psl.h>
+
+/* Interrupt sharing types. */
+#define IST_NONE 0 /* none */
+#define IST_PULSE 1 /* pulsed */
+#define IST_EDGE 2 /* edge-triggered */
+#define IST_LEVEL 3 /* level-triggered */
+
+/* Interrupt priority levels */
+#define _IPL_N 15
+#define _IPL_NSOFT 4
+
+#define IPL_NONE 0 /* nothing */
+#define IPL_SOFT 1
+#define IPL_SOFTCLOCK 2 /* timeouts */
+#define IPL_SOFTNET 3 /* protocol stacks */
+#define IPL_SOFTSERIAL 4 /* serial */
+
+#define IPL_SOFTNAMES { \
+ "misc", \
+ "clock", \
+ "net", \
+ "serial", \
+}
+
+struct intc_intrhand {
+ int (*ih_func)(void *);
+ void *ih_arg;
+ int ih_level; /* SR.I[0:3] value */
+ int ih_evtcode; /* INTEVT or INTEVT2(SH7709/SH7709A) */
+ int ih_idx; /* evtcode -> intrhand mapping */
+ struct evcount ih_count;
+};
+
+/* from 0x200 by 0x20 -> from 0 by 1 */
+#define EVTCODE_TO_MAP_INDEX(x) (((x) >> 5) - 0x10)
+#define EVTCODE_TO_IH_INDEX(x) \
+ __intc_evtcode_to_ih[EVTCODE_TO_MAP_INDEX(x)]
+#define EVTCODE_IH(x) (&__intc_intrhand[EVTCODE_TO_IH_INDEX(x)])
+extern int8_t __intc_evtcode_to_ih[];
+extern struct intc_intrhand __intc_intrhand[];
+
+void intc_init(void);
+void *intc_intr_establish(int, int, int, int (*)(void *), void *, const char *);
+void intc_intr_disestablish(void *);
+void intc_intr_enable(int);
+void intc_intr_disable(int);
+void intc_intr(int, int, int);
+
+void intpri_intr_priority(int evtcode, int level);
+
+/*
+ * software simulated interrupt
+ */
+struct sh_soft_intrhand {
+ TAILQ_ENTRY(sh_soft_intrhand) sih_q;
+ struct sh_soft_intr *sih_intrhead;
+ void (*sih_fn)(void *);
+ void *sih_arg;
+ int sih_pending;
+};
+
+struct sh_soft_intr {
+ TAILQ_HEAD(, sh_soft_intrhand) softintr_q;
+ struct evcnt softintr_evcnt;
+ struct simplelock softintr_slock;
+ unsigned long softintr_ipl;
+};
+
+#define softintr_schedule(arg) \
+do { \
+ struct sh_soft_intrhand *__sih = (arg); \
+ struct sh_soft_intr *__si = __sih->sih_intrhead; \
+ int __s; \
+ \
+ __s = _cpu_intr_suspend(); \
+ simple_lock(&__si->softintr_slock); \
+ if (__sih->sih_pending == 0) { \
+ TAILQ_INSERT_TAIL(&__si->softintr_q, __sih, sih_q); \
+ __sih->sih_pending = 1; \
+ setsoft(__si->softintr_ipl); \
+ } \
+ simple_unlock(&__si->softintr_slock); \
+ _cpu_intr_resume(__s); \
+} while (/*CONSTCOND*/0)
+
+void softintr_init(void);
+void *softintr_establish(int, void (*)(void *), void *);
+void softintr_disestablish(void *);
+void softintr_dispatch(int);
+void setsoft(int);
+
+/* XXX For legacy software interrupts. */
+extern struct sh_soft_intrhand *softnet_intrhand;
+
+#define setsoftnet() softintr_schedule(softnet_intrhand)
+
+#endif /* _KERNEL */
+
+#endif /* !_SH_INTR_H_ */
diff --git a/sys/arch/sh/include/limits.h b/sys/arch/sh/include/limits.h
new file mode 100644
index 00000000000..e8ceb6d29f5
--- /dev/null
+++ b/sys/arch/sh/include/limits.h
@@ -0,0 +1,57 @@
+/* $OpenBSD: limits.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: limits.h,v 1.1 1996/09/30 16:34:28 ws Exp $ */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 _SH_LIMITS_H_
+#define _SH_LIMITS_H_
+
+#include <sys/cdefs.h>
+
+#define MB_LEN_MAX 1 /* no multibyte characters */
+
+#if __POSIX_VISIBLE || __XPG_VISIBLE
+#ifndef SIZE_MAX
+#define SIZE_MAX UINT_MAX /* max value for a size_t */
+#endif
+#define SSIZE_MAX INT_MAX /* max value for a ssize_t */
+#endif
+
+#if __BSD_VISIBLE
+#define SIZE_T_MAX UINT_MAX /* max value for a size_t (historic) */
+
+#define UQUAD_MAX 0xffffffffffffffffULL /* max unsigned quad */
+#define QUAD_MAX 0x7fffffffffffffffLL /* max signed quad */
+#define QUAD_MIN (-0x7fffffffffffffffLL-1) /* min signed quad */
+#endif /* __BSD_VISIBLE */
+
+#endif /* _SH_LIMITS_H_ */
diff --git a/sys/arch/sh/include/lock.h b/sys/arch/sh/include/lock.h
new file mode 100644
index 00000000000..017e083c7dc
--- /dev/null
+++ b/sys/arch/sh/include/lock.h
@@ -0,0 +1,87 @@
+/* $OpenBSD: lock.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: lock.h,v 1.10 2006/01/03 01:29:46 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Gregory McGarry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+/*
+ * Machine-dependent spin lock operations.
+ */
+
+#ifndef _SH_LOCK_H_
+#define _SH_LOCK_H_
+
+typedef volatile u_int8_t __cpu_simple_lock_t;
+
+#define __SIMPLELOCK_LOCKED 0x80
+#define __SIMPLELOCK_UNLOCKED 0x00
+
+static __inline void
+__cpu_simple_lock_init(__cpu_simple_lock_t *alp)
+{
+ *alp = __SIMPLELOCK_UNLOCKED;
+}
+
+static __inline void
+__cpu_simple_lock(__cpu_simple_lock_t *alp)
+{
+ __asm volatile(
+ "1: tas.b %0 \n"
+ " bf 1b \n"
+ : "=m" (*alp));
+}
+
+static __inline int
+__cpu_simple_lock_try(__cpu_simple_lock_t *alp)
+{
+ int __rv;
+
+ __asm volatile(
+ " tas.b %0 \n"
+ " mov #0, %1 \n"
+ " rotcl %1 \n"
+ : "=m" (*alp), "=r" (__rv));
+
+ return (__rv);
+}
+
+static __inline void
+__cpu_simple_unlock(__cpu_simple_lock_t *alp)
+{
+ *alp = __SIMPLELOCK_UNLOCKED;
+}
+
+#endif /* !_SH_LOCK_H_ */
diff --git a/sys/arch/sh/include/locore.h b/sys/arch/sh/include/locore.h
new file mode 100644
index 00000000000..40fc0839f84
--- /dev/null
+++ b/sys/arch/sh/include/locore.h
@@ -0,0 +1,207 @@
+/* $OpenBSD: locore.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: locore.h,v 1.11 2006/01/23 22:32:50 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ */
+
+#if defined(SH3) && defined(SH4)
+#define MOV(x, r) mov.l .L_/**/x, r; mov.l @r, r
+#define REG_SYMBOL(x) .L_/**/x: .long _C_LABEL(__sh_/**/x)
+#define FUNC_SYMBOL(x) .L_/**/x: .long _C_LABEL(__sh_/**/x)
+#elif defined(SH3)
+#define MOV(x, r) mov.l .L_/**/x, r
+#define REG_SYMBOL(x) .L_/**/x: .long SH3_/**/x
+#define FUNC_SYMBOL(x) .L_/**/x: .long _C_LABEL(sh3_/**/x)
+#elif defined(SH4)
+#define MOV(x, r) mov.l .L_/**/x, r
+#define REG_SYMBOL(x) .L_/**/x: .long SH4_/**/x
+#define FUNC_SYMBOL(x) .L_/**/x: .long _C_LABEL(sh4_/**/x)
+#endif /* SH3 && SH4 */
+
+/*
+ * BANK1 r7 contains kernel stack top address.
+ * BANK1 r6 conatins current frame pointer. (per process)
+ */
+/*
+ * __EXCEPTION_ENTRY:
+ * + setup stack pointer
+ * + save all register to frame. (struct trapframe)
+ * + setup kernel stack.
+ * + change bank from 1 to 0
+ * + set BANK0 (r4, r5, r6) = (ssr, spc, ssp)
+ */
+#define __EXCEPTION_ENTRY ;\
+ /* Check kernel/user mode. */ ;\
+ mov #0x40, r3 ;\
+ swap.b r3, r3 ;\
+ stc ssr, r2 ;\
+ swap.w r3, r3 /* r3 = 0x40000000 */ ;\
+ mov r2, r0 /* r2 = r0 = SSR */ ;\
+ and r3, r0 ;\
+ tst r0, r0 /* if (SSR.MD == 0) T = 1 */ ;\
+ mov r14, r1 ;\
+ mov r6, r14 /* frame pointer */ ;\
+ bf/s 1f /* T==0 ...Exception from kernel mode */;\
+ mov r15, r0 ;\
+ /* Exception from user mode */ ;\
+ mov r7, r15 /* change to kernel stack */ ;\
+1: ;\
+ /* Save registers */ ;\
+ mov.l r1, @-r14 /* tf_r14 */ ;\
+ mov.l r0, @-r14 /* tf_r15 */ ;\
+ stc.l r0_bank,@-r14 /* tf_r0 */ ;\
+ stc.l r1_bank,@-r14 /* tf_r1 */ ;\
+ stc.l r2_bank,@-r14 /* tf_r2 */ ;\
+ stc.l r3_bank,@-r14 /* tf_r3 */ ;\
+ stc.l r4_bank,@-r14 /* tf_r4 */ ;\
+ stc.l r5_bank,@-r14 /* tf_r5 */ ;\
+ stc.l r6_bank,@-r14 /* tf_r6 */ ;\
+ stc.l r7_bank,@-r14 /* tf_r7 */ ;\
+ mov.l r8, @-r14 /* tf_r8 */ ;\
+ mov.l r9, @-r14 /* tf_r9 */ ;\
+ mov.l r10, @-r14 /* tf_r10 */ ;\
+ mov.l r11, @-r14 /* tf_r11 */ ;\
+ mov.l r12, @-r14 /* tf_r12 */ ;\
+ mov.l r13, @-r14 /* tf_r13 */ ;\
+ sts.l pr, @-r14 /* tf_pr */ ;\
+ sts.l mach, @-r14 /* tf_mach*/ ;\
+ sts.l macl, @-r14 /* tf_macl*/ ;\
+ mov.l r2, @-r14 /* tf_ssr */ ;\
+ stc.l spc, @-r14 /* tf_spc */ ;\
+ add #-8, r14 /* skip tf_ubc, tf_expevt */ ;\
+ mov r14, r6 /* store frame pointer */ ;\
+ /* Change register bank to 0 */ ;\
+ shlr r3 /* r3 = 0x20000000 */ ;\
+ stc sr, r1 /* r1 = SR */ ;\
+ not r3, r3 ;\
+ and r1, r3 ;\
+ ldc r3, sr /* SR.RB = 0 */ ;\
+ /* Set up argument. r4 = ssr, r5 = spc */ ;\
+ stc r2_bank,r4 ;\
+ stc spc, r5
+
+/*
+ * __EXCEPTION_RETURN:
+ * + block exception
+ * + restore all register from stack.
+ * + rte.
+ */
+#define __EXCEPTION_RETURN ;\
+ mov #0x10, r0 ;\
+ swap.b r0, r0 ;\
+ swap.w r0, r0 /* r0 = 0x10000000 */ ;\
+ stc sr, r1 ;\
+ or r0, r1 ;\
+ ldc r1, sr /* SR.BL = 1 */ ;\
+ stc r6_bank,r0 ;\
+ mov r0, r14 ;\
+ add #TF_SIZE, r0 ;\
+ ldc r0, r6_bank /* roll up frame pointer */ ;\
+ add #8, r14 /* skip tf_expevt, tf_ubc */ ;\
+ mov.l @r14+, r0 /* tf_spc */ ;\
+ ldc r0, spc ;\
+ mov.l @r14+, r0 /* tf_ssr */ ;\
+ ldc r0, ssr ;\
+ lds.l @r14+, macl /* tf_macl*/ ;\
+ lds.l @r14+, mach /* tf_mach*/ ;\
+ lds.l @r14+, pr /* tf_pr */ ;\
+ mov.l @r14+, r13 /* tf_r13 */ ;\
+ mov.l @r14+, r12 /* tf_r12 */ ;\
+ mov.l @r14+, r11 /* tf_r11 */ ;\
+ mov.l @r14+, r10 /* tf_r10 */ ;\
+ mov.l @r14+, r9 /* tf_r9 */ ;\
+ mov.l @r14+, r8 /* tf_r8 */ ;\
+ mov.l @r14+, r7 /* tf_r7 */ ;\
+ mov.l @r14+, r6 /* tf_r6 */ ;\
+ mov.l @r14+, r5 /* tf_r5 */ ;\
+ mov.l @r14+, r4 /* tf_r4 */ ;\
+ mov.l @r14+, r3 /* tf_r3 */ ;\
+ mov.l @r14+, r2 /* tf_r2 */ ;\
+ mov.l @r14+, r1 /* tf_r1 */ ;\
+ mov.l @r14+, r0 /* tf_r0 */ ;\
+ mov.l @r14+ r15 /* tf_r15 */ ;\
+ mov.l @r14+, r14 /* tf_r14 */ ;\
+ rte ;\
+ nop
+
+
+/*
+ * Macros to disable and enable exceptions (including interrupts).
+ * This modifies SR.BL
+ */
+#define __0x10 #0x10
+#define __0x78 #0x78
+
+#define __EXCEPTION_BLOCK(Rn, Rm) ;\
+ mov __0x10, Rn ;\
+ swap.b Rn, Rn ;\
+ swap.w Rn, Rn /* Rn = 0x10000000 */ ;\
+ stc sr, Rm ;\
+ or Rn, Rm ;\
+ ldc Rm, sr /* block exceptions */
+
+#define __EXCEPTION_UNBLOCK(Rn, Rm) ;\
+ mov __0x10, Rn ;\
+ swap.b Rn, Rn ;\
+ swap.w Rn, Rn /* Rn = 0x10000000 */ ;\
+ not Rn, Rn ;\
+ stc sr, Rm ;\
+ and Rn, Rm ;\
+ ldc Rm, sr /* unblock exceptions */
+
+/*
+ * Macros to disable and enable interrupts.
+ * This modifies SR.I[0-3]
+ */
+#define __INTR_MASK(Rn, Rm) ;\
+ mov __0x78, Rn ;\
+ shll Rn /* Rn = 0x000000f0 */ ;\
+ stc sr, Rm ;\
+ or Rn, Rm ;\
+ ldc Rm, sr /* mask all interrupt */
+
+#define __INTR_UNMASK(Rn, Rm) ;\
+ mov __0x78, Rn ;\
+ shll Rn /* Rn = 0x000000f0 */ ;\
+ not Rn, Rn ;\
+ stc sr, Rm ;\
+ and Rn, Rm ;\
+ ldc Rm, sr /* unmask all interrupt */
+
+#ifndef _LOCORE
+void sh3_switch_setup(struct proc *);
+void sh4_switch_setup(struct proc *);
+void sh3_switch_resume(struct proc *);
+void sh4_switch_resume(struct proc *);
+extern void (*__sh_switch_resume)(struct proc *);
+#endif /* !_LOCORE */
diff --git a/sys/arch/sh/include/mmu.h b/sys/arch/sh/include/mmu.h
new file mode 100644
index 00000000000..da1cdc501cb
--- /dev/null
+++ b/sys/arch/sh/include/mmu.h
@@ -0,0 +1,115 @@
+/* $OpenBSD: mmu.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: mmu.h,v 1.9 2006/03/04 01:55:03 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#ifndef _SH_MMU_H_
+#define _SH_MMU_H_
+
+/*
+ * Initialize routines.
+ * sh_mmu_init Assign function vector. Don't access hardware.
+ * Call as early as possible.
+ * sh_mmu_start Reset TLB entry, set default ASID, and start to
+ * translate addresses.
+ * Call after exception vector was installed.
+ *
+ * TLB access ops.
+ * sh_tlb_invalidate_addr invalidate TLB entris for given
+ * virtual addr with ASID.
+ * sh_tlb_invalidate_asid invalidate TLB entries for given ASID.
+ * sh_tlb_invalidate_all invalidate all non-wired TLB entries.
+ * sh_tlb_set_asid set ASID.
+ * sh_tlb_update load new PTE to TLB.
+ *
+ */
+
+void sh_mmu_init(void);
+void sh_mmu_information(void);
+void sh_tlb_set_asid(int);
+
+#ifdef SH3
+void sh3_mmu_start(void);
+void sh3_tlb_invalidate_addr(int, vaddr_t);
+void sh3_tlb_invalidate_asid(int);
+void sh3_tlb_invalidate_all(void);
+void sh3_tlb_update(int, vaddr_t, uint32_t);
+#endif
+
+#ifdef SH4
+void sh4_mmu_start(void);
+void sh4_tlb_invalidate_addr(int, vaddr_t);
+void sh4_tlb_invalidate_asid(int);
+void sh4_tlb_invalidate_all(void);
+void sh4_tlb_update(int, vaddr_t, uint32_t);
+#endif
+
+
+#if defined(SH3) && defined(SH4)
+extern uint32_t __sh_PTEH;
+
+extern void (*__sh_mmu_start)(void);
+extern void (*__sh_tlb_invalidate_addr)(int, vaddr_t);
+extern void (*__sh_tlb_invalidate_asid)(int);
+extern void (*__sh_tlb_invalidate_all)(void);
+extern void (*__sh_tlb_update)(int, vaddr_t, uint32_t);
+
+#define sh_mmu_start() (*__sh_mmu_start)()
+#define sh_tlb_invalidate_addr(a, va) (*__sh_tlb_invalidate_addr)(a, va)
+#define sh_tlb_invalidate_asid(a) (*__sh_tlb_invalidate_asid)(a)
+#define sh_tlb_invalidate_all() (*__sh_tlb_invalidate_all)()
+#define sh_tlb_update(a, va, pte) (*__sh_tlb_update)(a, va, pte)
+
+#elif defined(SH3)
+
+#define sh_mmu_start() sh3_mmu_start()
+#define sh_tlb_invalidate_addr(a, va) sh3_tlb_invalidate_addr(a, va)
+#define sh_tlb_invalidate_asid(a) sh3_tlb_invalidate_asid(a)
+#define sh_tlb_invalidate_all() sh3_tlb_invalidate_all()
+#define sh_tlb_update(a, va, pte) sh3_tlb_update(a, va, pte)
+
+#elif defined(SH4)
+
+#define sh_mmu_start() sh4_mmu_start()
+#define sh_tlb_invalidate_addr(a, va) sh4_tlb_invalidate_addr(a, va)
+#define sh_tlb_invalidate_asid(a) sh4_tlb_invalidate_asid(a)
+#define sh_tlb_invalidate_all() sh4_tlb_invalidate_all()
+#define sh_tlb_update(a, va, pte) sh4_tlb_update(a, va, pte)
+
+#endif
+
+#endif /* !_SH_MMU_H_ */
diff --git a/sys/arch/sh/include/mmu_sh3.h b/sys/arch/sh/include/mmu_sh3.h
new file mode 100644
index 00000000000..a8f5139e8ca
--- /dev/null
+++ b/sys/arch/sh/include/mmu_sh3.h
@@ -0,0 +1,90 @@
+/* $OpenBSD: mmu_sh3.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: mmu_sh3.h,v 1.6 2006/03/04 01:55:03 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#ifndef _SH_MMU_SH3_H_
+#define _SH_MMU_SH3_H_
+#include <sh/devreg.h>
+
+/* 128-entry 4-way set-associative */
+#define SH3_MMU_WAY 4
+#define SH3_MMU_ENTRY 32
+
+#define SH3_PTEH 0xfffffff0
+#define SH3_PTEH_ASID_MASK 0x000000ff
+#define SH3_PTEH_VPN_MASK 0xfffffc00
+#define SH3_PTEL 0xfffffff4
+#define SH3_PTEL_HWBITS 0x1ffff17e /* [28:12][8][6:1] */
+#define SH3_TTB 0xfffffff8
+#define SH3_TEA 0xfffffffc
+#define SH3_MMUCR 0xffffffe0
+#define SH3_MMUCR_AT 0x00000001
+#define SH3_MMUCR_IX 0x00000002
+#define SH3_MMUCR_TF 0x00000004
+#define SH3_MMUCR_RC 0x00000030
+#define SH3_MMUCR_SV 0x00000100
+
+/*
+ * memory-mapped TLB
+ */
+/* Address array */
+#define SH3_MMUAA 0xf2000000
+/* address specification */
+#define SH3_MMU_VPN_SHIFT 12
+#define SH3_MMU_VPN_MASK 0x0001f000 /* [16:12] */
+#define SH3_MMU_WAY_SHIFT 8
+#define SH3_MMU_WAY_MASK 0x00000300 /* [9:8] */
+/* data specification */
+#define SH3_MMU_D_VALID 0x00000100
+#define SH3_MMUAA_D_VPN_MASK_1K 0xfffe0c00 /* [31:17][11:10] */
+#define SH3_MMUAA_D_VPN_MASK_4K 0xfffe0000 /* [31:17] */
+#define SH3_MMUAA_D_ASID_MASK 0x000000ff
+
+/* Data array */
+#define SH3_MMUDA 0xf3000000
+#define SH3_MMUDA_D_PPN_MASK 0xfffffc00
+#define SH3_MMUDA_D_V 0x00000100
+#define SH3_MMUDA_D_PR_SHIFT 5
+#define SH3_MMUDA_D_PR_MASK 0x00000060 /* [6:5] */
+#define SH3_MMUDA_D_SZ 0x00000010
+#define SH3_MMUDA_D_C 0x00000008
+#define SH3_MMUDA_D_D 0x00000004
+#define SH3_MMUDA_D_SH 0x00000002
+
+#define SH3_TLB_DISABLE *(volatile uint32_t *)SH3_MMUCR = SH3_MMUCR_TF
+#endif /* !_SH_MMU_SH3_H_ */
diff --git a/sys/arch/sh/include/mmu_sh4.h b/sys/arch/sh/include/mmu_sh4.h
new file mode 100644
index 00000000000..c25a48c4748
--- /dev/null
+++ b/sys/arch/sh/include/mmu_sh4.h
@@ -0,0 +1,154 @@
+/* $OpenBSD: mmu_sh4.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: mmu_sh4.h,v 1.6 2006/03/04 01:55:03 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#ifndef _SH_MMU_SH4_H_
+#define _SH_MMU_SH4_H_
+#include <sh/devreg.h>
+
+/* ITLB 4-entry full-associative UTLB 64-entry full-associative */
+#define SH4_PTEH 0xff000000
+#define SH4_PTEH_VPN_MASK 0xfffffc00
+#define SH4_PTEH_ASID_MASK 0x000000ff
+#define SH4_PTEL 0xff000004
+#define SH4_PTEL_WT 0x00000001
+#define SH4_PTEL_SH 0x00000002
+#define SH4_PTEL_D 0x00000004
+#define SH4_PTEL_C 0x00000008
+#define SH4_PTEL_PR_SHIFT 5
+#define SH4_PTEL_PR_MASK 0x00000060 /* [5:6] */
+#define SH4_PTEL_SZ_MASK 0x00000090 /* [4][7] */
+#define SH4_PTEL_SZ_1K 0x00000000
+#define SH4_PTEL_SZ_4K 0x00000010
+#define SH4_PTEL_SZ_64K 0x00000080
+#define SH4_PTEL_SZ_1M 0x00000090
+#define SH4_PTEL_V 0x00000100
+#define SH4_PTEL_HWBITS 0x1ffff1ff /* [28:12]PFN [8:0]attr. */
+
+#define SH4_PTEA 0xff000034
+#define SH4_PTEA_SA_MASK 0x00000007
+#define SH4_PTEA_SA_TC 0x00000008
+#define SH4_TTB 0xff000008
+#define SH4_TEA 0xff00000c
+#define SH4_MMUCR 0xff000010
+#define SH4_MMUCR_AT 0x00000001
+#define SH4_MMUCR_TI 0x00000004
+#define SH4_MMUCR_SV 0x00000100
+#define SH4_MMUCR_SQMD 0x00000200
+#define SH4_MMUCR_URC_SHIFT 10
+#define SH4_MMUCR_URC_MASK 0x0000fc00 /* [10:15] */
+#define SH4_MMUCR_URB_SHIFT 18
+#define SH4_MMUCR_URB_MASK 0x00fc0000 /* [18:23] */
+#define SH4_MMUCR_LRUI_SHIFT 26
+#define SH4_MMUCR_LRUT_MASK 0xfc000000 /* [26:31] */
+
+#define SH4_MMUCR_MASK (SH4_MMUCR_LRUT_MASK | SH4_MMUCR_URB_MASK | \
+ SH4_MMUCR_URC_MASK | SH4_MMUCR_SQMD | SH4_MMUCR_SV | SH4_MMUCR_AT)
+/*
+ * memory-mapped TLB
+ * must be access from P2-area program.
+ * branch to the other area must be maed at least 8 instruction
+ * after access.
+ */
+#define SH4_ITLB_ENTRY 4
+#define SH4_UTLB_ENTRY 64
+
+/* ITLB */
+#define SH4_ITLB_AA 0xf2000000
+/* address specification (common for address and data array(0,1)) */
+#define SH4_ITLB_E_SHIFT 8
+#define SH4_ITLB_E_MASK 0x00000300 /* [9:8] */
+/* data specification */
+/* address-array */
+#define SH4_ITLB_AA_ASID_MASK 0x000000ff /* [7:0] */
+#define SH4_ITLB_AA_V 0x00000100
+#define SH4_ITLB_AA_VPN_SHIFT 10
+#define SH4_ITLB_AA_VPN_MASK 0xfffffc00 /* [31:10] */
+/* data-array 1 */
+#define SH4_ITLB_DA1 0xf3000000
+#define SH4_ITLB_DA1_SH 0x00000002
+#define SH4_ITLB_DA1_C 0x00000008
+#define SH4_ITLB_DA1_SZ_MASK 0x00000090 /* [7][4] */
+#define SH4_ITLB_DA1_SZ_1K 0x00000000
+#define SH4_ITLB_DA1_SZ_4K 0x00000010
+#define SH4_ITLB_DA1_SZ_64K 0x00000080
+#define SH4_ITLB_DA1_SZ_1M 0x00000090
+#define SH4_ITLB_DA1_PR 0x00000040
+#define SH4_ITLB_DA1_V 0x00000100
+#define SH4_ITLB_DA1_PPN_SHIFT 11
+#define SH4_ITLB_DA1_PPN_MASK 0x1ffffc00 /* [28:10] */
+/* data-array 2 */
+#define SH4_ITLB_DA2 0xf3800000
+#define SH4_ITLB_DA2_SA_MASK 0x00000003
+#define SH4_ITLB_DA2_TC 0x00000004
+
+/* UTLB */
+#define SH4_UTLB_AA 0xf6000000
+/* address specification (common for address and data array(0,1)) */
+#define SH4_UTLB_E_SHIFT 8
+#define SH4_UTLB_E_MASK 0x00003f00
+#define SH4_UTLB_A 0x00000080
+/* data specification */
+/* address-array */
+#define SH4_UTLB_AA_VPN_MASK 0xfffffc00 /* [31:10] */
+#define SH4_UTLB_AA_D 0x00000200
+#define SH4_UTLB_AA_V 0x00000100
+#define SH4_UTLB_AA_ASID_MASK 0x000000ff /* [7:0] */
+/* data-array 1 */
+#define SH4_UTLB_DA1 0xf7000000
+#define SH4_UTLB_DA1_WT 0x00000001
+#define SH4_UTLB_DA1_SH 0x00000002
+#define SH4_UTLB_DA1_D 0x00000004
+#define SH4_UTLB_DA1_C 0x00000008
+#define SH4_UTLB_DA1_SZ_MASK 0x00000090 /* [7][4] */
+#define SH4_UTLB_DA1_SZ_1K 0x00000000
+#define SH4_UTLB_DA1_SZ_4K 0x00000010
+#define SH4_UTLB_DA1_SZ_64K 0x00000080
+#define SH4_UTLB_DA1_SZ_1M 0x00000090
+#define SH4_UTLB_DA1_PR_SHIFT 5
+#define SH4_UTLB_DA1_PR_MASK 0x00000060
+#define SH4_UTLB_DA1_V 0x00000100
+#define SH4_UTLB_DA1_PPN_SHIFT 11
+#define SH4_UTLB_DA1_PPN_MASK 0x1ffffc00 /* [28:10] */
+/* data-array 2 */
+#define SH4_UTLB_DA2 0xf7800000
+#define SH4_UTLB_DA2_SA_MASK 0x00000003
+#define SH4_UTLB_DA2_TC 0x00000004
+
+#define SH4_TLB_DISABLE *(volatile uint32_t *)SH4_MMUCR = SH4_MMUCR_TI
+#endif /* !_SH_MMU_SH4_H_ */
diff --git a/sys/arch/sh/include/param.h b/sys/arch/sh/include/param.h
new file mode 100644
index 00000000000..9a4493af3ee
--- /dev/null
+++ b/sys/arch/sh/include/param.h
@@ -0,0 +1,137 @@
+/* $OpenBSD: param.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: param.h,v 1.15 2006/08/28 13:43:35 yamt Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)param.h 5.8 (Berkeley) 6/28/91
+ */
+
+/*
+ * SuperH dependent constants.
+ */
+
+#ifndef _SH_PARAM_H_
+#define _SH_PARAM_H_
+
+#define _MACHINE_ARCH sh
+#define MACHINE_ARCH "sh"
+
+#ifndef MID_MACHINE
+#define MID_MACHINE MID_SH3
+#endif
+
+#if defined(_KERNEL) && !defined(_LOCORE)
+#include <sh/cpu.h>
+#endif
+
+/*
+ * We use 4K pages on the sh3/sh4. Override the PAGE_* definitions
+ * to be compile-time constants.
+ */
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1 << PAGE_SHIFT)
+#define PAGE_MASK (PAGE_SIZE - 1)
+
+#define PGSHIFT PAGE_SHIFT
+#define NBPG PAGE_SIZE
+#define PGOFSET PAGE_MASK
+
+/*
+ * Round p (pointer or byte index) up to a correctly-aligned value
+ * for all data types (int, long, ...). The result is u_int and
+ * must be cast to any desired pointer type.
+ *
+ * ALIGNED_POINTER is a boolean macro that checks whether an address
+ * is valid to fetch data elements of type t from on this architecture.
+ * This does not reflect the optimal alignment, just the possibility
+ * (within reasonable limits).
+ *
+ */
+#define ALIGNBYTES (sizeof(int) - 1)
+#define ALIGN(p) (((u_int)(p) + ALIGNBYTES) & ~ALIGNBYTES)
+#define ALIGNED_POINTER(p, t) ((((u_long)(p)) & (sizeof(t) - 1)) == 0)
+
+#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
+#define DEV_BSIZE (1 << DEV_BSHIFT)
+#define BLKDEV_IOSIZE 2048
+#define MAXPHYS (64 * 1024) /* max raw I/O transfer size */
+
+/*
+ * u-space.
+ */
+#define UPAGES 2 /* pages of u-area */
+#define USPACE (UPAGES * NBPG) /* total size of u-area */
+#define USPACE_ALIGN (0)
+#if UPAGES == 1
+#error "too small u-area"
+#elif UPAGES == 2
+#define P1_STACK /* kernel stack is P1-area */
+#else
+#undef P1_STACK /* kernel stack is P3-area */
+#endif
+
+#ifndef MSGBUFSIZE
+#define MSGBUFSIZE NBPG /* default message buffer size */
+#endif
+
+#define btoc(x) (((x) + PAGE_MASK) >> PAGE_SHIFT)
+#define ctob(x) ((x) << PAGE_SHIFT)
+
+#define btodb(bytes) /* calculates (bytes / DEV_BSIZE) */ \
+ ((bytes) >> DEV_BSHIFT)
+#define dbtob(db) /* calculates (db * DEV_BSIZE) */ \
+ ((db) << DEV_BSHIFT)
+
+/*
+ * Constants related to network buffer management.
+ * MCLBYTES must be no larger than NBPG (the software page size), and,
+ * on machines that exchange pages of input or output buffers with mbuf
+ * clusters (MAPPED_MBUFS), MCLBYTES must also be an integral multiple
+ * of the hardware page size.
+ */
+#define MSIZE 256 /* size of an mbuf */
+
+#define MCLSHIFT 11 /* convert bytes to m_buf clusters */
+ /* 2K cluster can hold Ether frame */
+#define MCLBYTES (1 << MCLSHIFT) /* size of a m_buf cluster */
+
+#define NMBCLUSTERS 4096 /* map size, max cluster allocation */
+
+/*
+ * Minimum and maximum sizes of the kernel malloc arena in PAGE_SIZE-sized
+ * logical pages.
+ */
+#define NKMEMPAGES_MIN_DEFAULT ((4 * 1024 * 1024) >> PAGE_SHIFT)
+#define NKMEMPAGES_MAX_DEFAULT ((64 * 1024 * 1024) >> PAGE_SHIFT)
+
+#endif /* !_SH3_PARAM_H_ */
diff --git a/sys/arch/sh/include/pcb.h b/sys/arch/sh/include/pcb.h
new file mode 100644
index 00000000000..2dbc63c7cfa
--- /dev/null
+++ b/sys/arch/sh/include/pcb.h
@@ -0,0 +1,55 @@
+/* $OpenBSD: pcb.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: pcb.h,v 1.7 2002/05/09 12:28:08 uch Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#ifndef _SH_PCB_H_
+#define _SH_PCB_H_
+
+#include <sh/frame.h>
+
+struct pcb {
+ struct switchframe pcb_sf; /* kernel context for resume */
+ caddr_t pcb_onfault; /* for copyin/out fault */
+ int pcb_faultbail; /* bail out before call uvm_fault. */
+};
+
+struct md_coredump {
+};
+
+extern struct pcb *curpcb;
+#endif /* !_SH_PCB_H_ */
diff --git a/sys/arch/sh/include/pmap.h b/sys/arch/sh/include/pmap.h
new file mode 100644
index 00000000000..b26dd562137
--- /dev/null
+++ b/sys/arch/sh/include/pmap.h
@@ -0,0 +1,91 @@
+/* $OpenBSD: pmap.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: pmap.h,v 1.28 2006/04/10 23:12:11 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+/*
+ * OpenBSD/sh pmap:
+ * pmap.pm_ptp[512] ... 512 slot of page table page
+ * page table page contains 1024 PTEs. (PAGE_SIZE / sizeof(pt_entry_t))
+ * | PTP 11bit | PTOFSET 10bit | PGOFSET 12bit |
+ */
+
+#ifndef _SH_PMAP_H_
+#define _SH_PMAP_H_
+#include <sys/queue.h>
+#include <sh/pte.h>
+
+#define PMAP_STEAL_MEMORY
+#define PMAP_GROWKERNEL
+
+#define __PMAP_PTP_N 512 /* # of page table page maps 2GB. */
+typedef struct pmap {
+ pt_entry_t **pm_ptp;
+ int pm_asid;
+ int pm_refcnt;
+ struct pmap_statistics pm_stats; /* pmap statistics */
+} *pmap_t;
+extern struct pmap __pmap_kernel;
+
+void pmap_bootstrap(void);
+void pmap_proc_iflush(struct proc *, vaddr_t, size_t);
+#define pmap_unuse_final(p) do { /* nothing */ } while (0)
+#define pmap_kernel() (&__pmap_kernel)
+#define pmap_deactivate(pmap) do { /* nothing */ } while (0)
+#define pmap_update(pmap) do { /* nothing */ } while (0)
+#define pmap_copy(dp,sp,d,l,s) do { /* nothing */ } while (0)
+#define pmap_collect(pmap) do { /* nothing */ } while (0)
+#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)
+#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
+#define pmap_phys_address(frame) ((paddr_t)(ptoa(frame)))
+
+/* ARGSUSED */
+static __inline void
+pmap_remove_all(struct pmap *pmap)
+{
+ /* Nothing. */
+}
+
+#define __HAVE_PMAP_DIRECT
+#define pmap_map_direct(pg) SH3_PHYS_TO_P1SEG(VM_PAGE_TO_PHYS(pg))
+#define pmap_unmap_direct(va) PHYS_TO_VM_PAGE(SH3_P1SEG_TO_PHYS((va)))
+
+/* MD pmap utils. */
+pt_entry_t *__pmap_pte_lookup(pmap_t, vaddr_t);
+pt_entry_t *__pmap_kpte_lookup(vaddr_t);
+boolean_t __pmap_pte_load(pmap_t, vaddr_t, int);
+#endif /* !_SH_PMAP_H_ */
diff --git a/sys/arch/sh/include/proc.h b/sys/arch/sh/include/proc.h
new file mode 100644
index 00000000000..a308274bf3e
--- /dev/null
+++ b/sys/arch/sh/include/proc.h
@@ -0,0 +1,69 @@
+/* $OpenBSD: proc.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: proc.h,v 1.10 2005/12/11 12:18:58 christos Exp $ */
+
+/*
+ * Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
+ * Copyright (c) 1991 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)proc.h 7.1 (Berkeley) 5/15/91
+ */
+
+#ifndef _SH_PROC_H_
+#define _SH_PROC_H_
+
+/*
+ * Machine-dependent part of the proc structure for sh.
+ */
+
+#include <machine/param.h>
+
+/* Kernel stack PTE */
+struct md_upte {
+ uint32_t addr;
+ uint32_t data;
+};
+
+struct mdproc {
+ struct trapframe *md_regs; /* user context */
+ struct pcb *md_pcb; /* pcb access address */
+ volatile int md_astpending; /* AST pending on return to userland */
+ int md_flags; /* machine-dependent flags */
+ /* u-area PTE: *2 .. SH4 data/address data array access */
+ struct md_upte md_upte[UPAGES * 2];
+};
+
+/* md_flags */
+#define MDP_USEDFPU 0x0001 /* has used the FPU */
+
+#ifdef _KERNEL
+#ifndef _LOCORE
+extern void sh_proc0_init(void);
+extern struct md_upte *curupte; /* SH3 wired u-area hack */
+#endif /* _LOCORE */
+#endif /* _KERNEL */
+#endif /* !_SH_PROC_H_ */
diff --git a/sys/arch/sh/include/profile.h b/sys/arch/sh/include/profile.h
new file mode 100644
index 00000000000..2b2caf62119
--- /dev/null
+++ b/sys/arch/sh/include/profile.h
@@ -0,0 +1,74 @@
+/* $OpenBSD: profile.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: profile.h,v 1.4 2002/04/28 17:10:36 uch Exp $ */
+
+/*-
+ * Copyright (c) 2000 Tsubai Masanari. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__ELF__)
+#define _MCOUNT_DECL static void _mcount
+#else
+#define _MCOUNT_DECL static void mcount
+#endif
+
+#define MCOUNT __asm (" \n\
+ .text \n\
+ .align 2 \n\
+ .globl __mcount \n\
+__mcount: \n\
+ mov.l r0,@-r15 \n\
+ mov.l r4,@-r15 \n\
+ mov.l r5,@-r15 \n\
+ mov.l r6,@-r15 \n\
+ mov.l r7,@-r15 \n\
+ mov.l r14,@-r15 \n\
+ sts.l pr,@-r15 \n\
+ mov r15,r14 \n\
+ \n\
+ mov.l 1f,r1 ! _mcount \n\
+ sts pr,r4 ! frompc \n\
+ mov r0,r5 ! selfpc \n\
+ jsr @r1 \n\
+ nop \n\
+ \n\
+ mov r14,r15 \n\
+ lds.l @r15+,pr \n\
+ mov.l @r15+,r14 \n\
+ mov.l @r15+,r7 \n\
+ mov.l @r15+,r6 \n\
+ mov.l @r15+,r5 \n\
+ mov.l @r15+,r4 \n\
+ mov.l @r15+,r0 \n\
+ \n\
+ jmp @r0 ! return \n\
+ nop \n\
+ \n\
+ .align 2 \n\
+1: .long _mcount ");
+
+#ifdef _KERNEL
+#define MCOUNT_ENTER s = splhigh()
+#define MCOUNT_EXIT splx(s)
+#endif
diff --git a/sys/arch/sh/include/psl.h b/sys/arch/sh/include/psl.h
new file mode 100644
index 00000000000..8a45a23a3fd
--- /dev/null
+++ b/sys/arch/sh/include/psl.h
@@ -0,0 +1,76 @@
+/* $OpenBSD: psl.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: psl.h,v 1.8 2005/12/11 12:18:58 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)psl.h 5.2 (Berkeley) 1/18/91
+ */
+
+#ifndef _SH_PSL_H_
+#define _SH_PSL_H_
+
+/*
+ * SuperH Processer Status Register.
+ */
+#define PSL_TBIT 0x00000001 /* T bit */
+#define PSL_SBIT 0x00000002 /* S bit */
+#define PSL_IMASK 0x000000f0 /* Interrupt Mask bit */
+#define PSL_QBIT 0x00000100 /* Q bit */
+#define PSL_MBIT 0x00000200 /* M bit */
+#define PSL_BL 0x10000000 /* Exception Block bit */
+#define PSL_RB 0x20000000 /* Register Bank bit */
+#define PSL_MD 0x40000000 /* Processor Mode bit */
+ /* 1 = kernel, 0 = user */
+
+#define PSL_MBO 0x00000000 /* must be one bits */
+#define PSL_MBZ 0x8ffffc0c /* must be zero bits */
+
+#define PSL_USERSET 0
+#define PSL_USERSTATIC (PSL_BL|PSL_RB|PSL_MD|PSL_IMASK|PSL_MBO|PSL_MBZ)
+
+#define KERNELMODE(sr) ((sr) & PSL_MD)
+
+#ifdef _KERNEL
+#ifndef _LOCORE
+/* SR.IMASK */
+int _cpu_intr_raise(int);
+int _cpu_intr_suspend(void);
+int _cpu_intr_resume(int);
+/* SR.BL */
+int _cpu_exception_suspend(void);
+void _cpu_exception_resume(int);
+#endif /* !_LOCORE */
+
+#include <machine/intr.h>
+#endif /* _KERNEL */
+
+#endif /* !_SH_PSL_H_ */
diff --git a/sys/arch/sh/include/pte.h b/sys/arch/sh/include/pte.h
new file mode 100644
index 00000000000..b3034504cb9
--- /dev/null
+++ b/sys/arch/sh/include/pte.h
@@ -0,0 +1,99 @@
+/* $OpenBSD: pte.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: pte.h,v 1.11 2006/03/04 01:55:03 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#ifndef _SH_PTE_H_
+#define _SH_PTE_H_
+
+/*
+ * OpenBSD/sh PTE format.
+ *
+ * [Hardware bit]
+ * SH3
+ * PPN V PR SZ C D SH
+ * [28:10][8][6:5][4][3][2][1]
+ *
+ * SH4
+ * V SZ PR SZ C D SH WT
+ * [28:10][8][7][6:5][4][3][2][1][0]
+ *
+ * [Software bit]
+ * [31] - PMAP_WIRED bit (not hardware wired entry)
+ * [11:9] - SH4 PCMCIA Assistant bit. (space attribute bit only)
+ */
+
+/*
+ * Hardware bits
+ */
+#define PG_PPN 0x1ffff000 /* Physical page number mask */
+#define PG_V 0x00000100 /* Valid */
+#define PG_PR_MASK 0x00000060 /* Page protection mask */
+#define PG_PR_URW 0x00000060 /* kernel/user read/write */
+#define PG_PR_URO 0x00000040 /* kernel/user read only */
+#define PG_PR_KRW 0x00000020 /* kernel read/write */
+#define PG_PR_KRO 0x00000000 /* kernel read only */
+#define PG_4K 0x00000010 /* page size 4KB */
+#define PG_C 0x00000008 /* Cacheable */
+#define PG_D 0x00000004 /* Dirty */
+#define PG_SH 0x00000002 /* Share status */
+#define PG_WT 0x00000001 /* Write-through (SH4 only) */
+
+#define PG_HW_BITS 0x1ffff17e /* [28:12][8][6:1] */
+
+/*
+ * Software bits
+ */
+#define _PG_WIRED 0x80000000
+
+/* SH4 PCMCIA MMU support bits */
+/* PTEA SA (Space Attribute bit) */
+#define _PG_PCMCIA 0x00000e00 /* [11:9] */
+#define _PG_PCMCIA_SHIFT 9
+#define _PG_PCMCIA_NONE 0x00000000 /* Non PCMCIA space */
+#define _PG_PCMCIA_IO 0x00000200 /* IOIS16 signal */
+#define _PG_PCMCIA_IO8 0x00000400 /* 8 bit I/O */
+#define _PG_PCMCIA_IO16 0x00000600 /* 16 bit I/O */
+#define _PG_PCMCIA_MEM8 0x00000800 /* 8 bit common memory */
+#define _PG_PCMCIA_MEM16 0x00000a00 /* 16 bit common memory */
+#define _PG_PCMCIA_ATTR8 0x00000c00 /* 8 bit attribute */
+#define _PG_PCMCIA_ATTR16 0x00000e00 /* 16 bit attribute */
+
+#ifndef _LOCORE
+typedef uint32_t pt_entry_t;
+#endif /* _LOCORE */
+#endif /* !_SH_PTE_H_ */
diff --git a/sys/arch/sh/include/ptrace.h b/sys/arch/sh/include/ptrace.h
new file mode 100644
index 00000000000..3c25fb88b73
--- /dev/null
+++ b/sys/arch/sh/include/ptrace.h
@@ -0,0 +1,40 @@
+/* $OpenBSD: ptrace.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: ptrace.h,v 1.3 2002/02/28 01:58:53 uch Exp $ */
+
+/*
+ * Copyright (c) 1993 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.
+ * 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.
+ */
+
+/*
+ * SuperH ptrace definitions
+ */
+
+#define PT_GETREGS (PT_FIRSTMACH + 1)
+#define PT_SETREGS (PT_FIRSTMACH + 2)
+
diff --git a/sys/arch/sh/include/reg.h b/sys/arch/sh/include/reg.h
new file mode 100644
index 00000000000..ec499656bb1
--- /dev/null
+++ b/sys/arch/sh/include/reg.h
@@ -0,0 +1,103 @@
+/* $OpenBSD: reg.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: reg.h,v 1.5 2005/12/11 12:18:58 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)reg.h 5.5 (Berkeley) 1/18/91
+ */
+
+#ifndef _SH_REG_H_
+#define _SH_REG_H_
+
+/*
+ * Location of the users' stored
+ * registers within appropriate frame of 'trap' and 'syscall', relative to
+ * base of stack frame.
+ *
+ * XXX
+ * The #defines aren't used in the kernel, but some user-level code still
+ * expects them.
+ */
+
+/* When referenced during a trap/exception, registers are at these offsets */
+
+#define tSPC (0)
+#define tSSR (1)
+#define tPR (2)
+#define tR14 (3)
+#define tR13 (4)
+#define tR12 (5)
+#define tR11 (6)
+#define tR10 (7)
+#define tR9 (8)
+
+#define tR8 (11)
+#define tR7 (12)
+#define tR6 (13)
+#define tR5 (14)
+#define tR4 (15)
+#define tR3 (16)
+#define tR2 (17)
+#define tR1 (18)
+#define tR0 (19)
+
+/*
+ * Registers accessible to ptrace(2) syscall for debugger
+ * The machine-dependent code for PT_{SET,GET}REGS needs to
+ * use whichver order, defined above, is correct, so that it
+ * is all invisible to the user.
+ */
+struct reg {
+ int r_spc;
+ int r_ssr;
+ int r_pr;
+ int r_mach;
+ int r_macl;
+ int r_r15;
+ int r_r14;
+ int r_r13;
+ int r_r12;
+ int r_r11;
+ int r_r10;
+ int r_r9;
+ int r_r8;
+ int r_r7;
+ int r_r6;
+ int r_r5;
+ int r_r4;
+ int r_r3;
+ int r_r2;
+ int r_r1;
+ int r_r0;
+};
+
+#endif /* !_SH_REG_H_ */
diff --git a/sys/arch/sh/include/rtcreg.h b/sys/arch/sh/include/rtcreg.h
new file mode 100644
index 00000000000..7ebd9274e38
--- /dev/null
+++ b/sys/arch/sh/include/rtcreg.h
@@ -0,0 +1,106 @@
+/* $OpenBSD: rtcreg.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: rtcreg.h,v 1.10 2006/09/03 12:38:34 uwe Exp $ */
+
+/*-
+ * Copyright (C) 1999 SAITOH Masanobu. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SH_RTCREG_H_
+#define _SH_RTCREG_H_
+#include <sh/devreg.h>
+
+/*
+ * RTC
+ */
+#define SH3_R64CNT 0xfffffec0
+#define SH3_RSECCNT 0xfffffec2
+#define SH3_RMINCNT 0xfffffec4
+#define SH3_RHRCNT 0xfffffec6
+#define SH3_RWKCNT 0xfffffec8
+#define SH3_RDAYCNT 0xfffffeca
+#define SH3_RMONCNT 0xfffffecc
+#define SH3_RYRCNT 0xfffffece
+#define SH3_RSECAR 0xfffffed0
+#define SH3_RMINAR 0xfffffed2
+#define SH3_RHRAR 0xfffffed4
+#define SH3_RWKAR 0xfffffed6
+#define SH3_RDAYAR 0xfffffed8
+#define SH3_RMONAR 0xfffffeda
+#define SH3_RCR1 0xfffffedc
+#define SH3_RCR2 0xfffffede
+
+#define SH4_R64CNT 0xffc80000
+#define SH4_RSECCNT 0xffc80004
+#define SH4_RMINCNT 0xffc80008
+#define SH4_RHRCNT 0xffc8000c
+#define SH4_RWKCNT 0xffc80010
+#define SH4_RDAYCNT 0xffc80014
+#define SH4_RMONCNT 0xffc80018
+#define SH4_RYRCNT 0xffc8001c /* 16 bit */
+#define SH4_RSECAR 0xffc80020
+#define SH4_RMINAR 0xffc80024
+#define SH4_RHRAR 0xffc80028
+#define SH4_RWKAR 0xffc8002c
+#define SH4_RDAYAR 0xffc80030
+#define SH4_RMONAR 0xffc80034
+#define SH4_RCR1 0xffc80038
+#define SH4_RCR2 0xffc8003c
+
+#define SH_RCR1_CF 0x80 /* carry flag */
+#define SH_RCR1_CIE 0x10 /* carry interrupt enable */
+#define SH_RCR1_AIE 0x08 /* alarm interrupt enable */
+#define SH_RCR1_AF 0x01 /* alarm flag */
+
+#define SH_RCR2_PEF 0x80 /* periodic interrupt flag */
+#define SH_RCR2_PES2 0x40 /* periodic interrupt freq */
+#define SH_RCR2_PES1 0x20 /* -//- */
+#define SH_RCR2_PES0 0x10 /* -//- */
+#define SH_RCR2_ENABLE 0x08
+#define SH_RCR2_ADJ 0x04 /* second adjustment */
+#define SH_RCR2_RESET 0x02
+#define SH_RCR2_START 0x01
+
+#ifndef _LOCORE
+#if defined(SH3) && defined(SH4)
+extern uint32_t __sh_R64CNT;
+extern uint32_t __sh_RSECCNT;
+extern uint32_t __sh_RMINCNT;
+extern uint32_t __sh_RHRCNT;
+extern uint32_t __sh_RWKCNT;
+extern uint32_t __sh_RDAYCNT;
+extern uint32_t __sh_RMONCNT;
+extern uint32_t __sh_RYRCNT;
+extern uint32_t __sh_RSECAR;
+extern uint32_t __sh_RMINAR;
+extern uint32_t __sh_RHRAR;
+extern uint32_t __sh_RWKAR;
+extern uint32_t __sh_RDAYAR;
+extern uint32_t __sh_RMONAR;
+extern uint32_t __sh_RCR1;
+extern uint32_t __sh_RCR2;
+#endif /* SH3 && SH4 */
+#endif /* !_LOCORE */
+
+#endif /* !_SH_RTCREG_H_ */
diff --git a/sys/arch/sh/include/setjmp.h b/sys/arch/sh/include/setjmp.h
new file mode 100644
index 00000000000..fb8887ca147
--- /dev/null
+++ b/sys/arch/sh/include/setjmp.h
@@ -0,0 +1,23 @@
+/* $OpenBSD: setjmp.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: setjmp.h,v 1.3 2006/01/05 00:50:23 uwe Exp $ */
+
+/*
+ * machine/setjmp.h: machine dependent setjmp-related information.
+ */
+
+#define _JBLEN 14 /* size, in longs, of a jmp_buf */
+
+#define _JB_REG_PR 0
+#define _JB_REG_R8 1
+#define _JB_REG_R9 2
+#define _JB_REG_R10 3
+#define _JB_REG_R11 4
+#define _JB_REG_R12 5
+#define _JB_REG_R13 6
+#define _JB_REG_R14 7
+#define _JB_REG_R15 8
+
+#define _JB_HAS_MASK 9
+#define _JB_SIGMASK 10 /* occupies sizeof(sigset_t) = 4 slots */
+
+#define _JB_REG_SP _JB_REG_R15
diff --git a/sys/arch/sh/include/sh_opcode.h b/sys/arch/sh/include/sh_opcode.h
new file mode 100644
index 00000000000..3fad67a443c
--- /dev/null
+++ b/sys/arch/sh/include/sh_opcode.h
@@ -0,0 +1,163 @@
+/* $OpenBSD: sh_opcode.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: sh_opcode.h,v 1.3 2002/04/28 17:10:36 uch Exp $ */
+
+typedef union {
+ unsigned word;
+
+#if _BYTE_ORDER == BIG_ENDIAN
+ struct {
+ unsigned op: 16;
+ } oType;
+
+ struct {
+ unsigned op1: 4;
+ unsigned n: 4;
+ unsigned op2: 8;
+ } nType;
+
+ struct {
+ unsigned op1: 4;
+ unsigned m: 4;
+ unsigned op2: 8;
+ } mType;
+
+ struct {
+ unsigned op1: 4;
+ unsigned n: 4;
+ unsigned m: 4;
+ unsigned op2: 4;
+ } nmType;
+
+ struct {
+ unsigned op: 8;
+ unsigned m: 4;
+ unsigned d: 4;
+ } mdType;
+
+ struct {
+ unsigned op: 8;
+ unsigned n: 4;
+ unsigned d: 4;
+ } nd4Type;
+
+ struct {
+ unsigned op: 4;
+ unsigned n: 4;
+ unsigned m: 4;
+ unsigned d: 4;
+ } nmdType;
+
+ struct {
+ unsigned op: 8;
+ unsigned d: 8;
+ } dType;
+
+ struct {
+ unsigned op: 4;
+ unsigned d: 12;
+ } d12Type;
+
+ struct {
+ unsigned op: 4;
+ unsigned n: 4;
+ unsigned d: 8;
+ } nd8Type;
+
+ struct {
+ unsigned op: 8;
+ unsigned i: 8;
+ } iType;
+
+ struct {
+ unsigned op: 4;
+ unsigned n: 4;
+ unsigned i: 8;
+ } niType;
+#endif
+#if _BYTE_ORDER == LITTLE_ENDIAN
+struct {
+ unsigned op: 16;
+ } oType;
+
+ struct {
+ unsigned op2: 8;
+ unsigned n: 4;
+ unsigned op1: 4;
+ } nType;
+
+ struct {
+ unsigned op2: 8;
+ unsigned m: 4;
+ unsigned op1: 4;
+ } mType;
+
+ struct {
+ unsigned op2: 4;
+ unsigned m: 4;
+ unsigned n: 4;
+ unsigned op1: 4;
+ } nmType;
+
+ struct {
+ unsigned d: 4;
+ unsigned m: 4;
+ unsigned op: 8;
+ } mdType;
+
+ struct {
+ unsigned d: 4;
+ unsigned n: 4;
+ unsigned op: 8;
+ } nd4Type;
+
+ struct {
+ unsigned d: 4;
+ unsigned m: 4;
+ unsigned n: 4;
+ unsigned op: 4;
+ } nmdType;
+
+ struct {
+ unsigned d: 8;
+ unsigned op: 8;
+ } dType;
+
+ struct {
+ unsigned d: 12;
+ unsigned op: 4;
+ } d12Type;
+
+ struct {
+ unsigned d: 8;
+ unsigned n: 4;
+ unsigned op: 4;
+ } nd8Type;
+
+ struct {
+ unsigned i: 8;
+ unsigned op: 8;
+ } iType;
+
+ struct {
+ unsigned i: 8;
+ unsigned n: 4;
+ unsigned op: 4;
+ } niType;
+#endif
+} InstFmt;
+
+#define OP_BF 0x8b
+#define OP_BFS 0x8f
+#define OP_BT 0x89
+#define OP_BTS 0x8d
+#define OP_BRA 0xa
+#define OP_BSR 0xb
+#define OP1_BRAF 0x0
+#define OP2_BRAF 0x23
+#define OP1_BSRF 0x0
+#define OP2_BSRF 0x03
+#define OP1_JMP 0x4
+#define OP2_JMP 0x2b
+#define OP1_JSR 0x4
+#define OP2_JSR 0x0b
+#define OP_RTS 0xffff
diff --git a/sys/arch/sh/include/signal.h b/sys/arch/sh/include/signal.h
new file mode 100644
index 00000000000..b742e598ef5
--- /dev/null
+++ b/sys/arch/sh/include/signal.h
@@ -0,0 +1,80 @@
+/* $OpenBSD: signal.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: signal.h,v 1.12 2005/12/11 12:18:58 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)signal.h 7.16 (Berkeley) 3/17/91
+ */
+
+#ifndef _SH_SIGNAL_H_
+#define _SH_SIGNAL_H_
+
+#include <sys/cdefs.h>
+
+typedef int sig_atomic_t;
+
+#if __BSD_VISIBLE || __XPG_VISIBLE >= 420
+/*
+ * Information pushed on stack when a signal is delivered.
+ * This is used by the kernel to restore state following
+ * execution of the signal handler. It is also made available
+ * to the handler to allow it to restore state properly if
+ * a non-standard exit is performed.
+ */
+struct sigcontext {
+ int sc_spc;
+ int sc_ssr;
+ int sc_pr;
+ int sc_r14;
+ int sc_r13;
+ int sc_r12;
+ int sc_r11;
+ int sc_r10;
+ int sc_r9;
+ int sc_r8;
+ int sc_r7;
+ int sc_r6;
+ int sc_r5;
+ int sc_r4;
+ int sc_r3;
+ int sc_r2;
+ int sc_r1;
+ int sc_r0;
+ int sc_r15;
+
+ int sc_onstack; /* sigstack state to restore */
+
+ int sc_expevt; /* XXX should be above */
+ int sc_err;
+
+ unsigned int sc_mask; /* signal mask to restore */
+};
+
+#endif /* __BSD_VISIBLE || __XPG_VISIBLE >= 420 */
+#endif /* !_SH_SIGNAL_H_ */
diff --git a/sys/arch/sh/include/spinlock.h b/sys/arch/sh/include/spinlock.h
new file mode 100644
index 00000000000..6fc31bec819
--- /dev/null
+++ b/sys/arch/sh/include/spinlock.h
@@ -0,0 +1,52 @@
+/* $OpenBSD: spinlock.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: lock.h,v 1.10 2006/01/03 01:29:46 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Gregory McGarry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+/*
+ * Machine-dependent spin lock operations.
+ */
+
+#ifndef _SH_SPINLOCK_H_
+#define _SH_SPINLOCK_H_
+
+typedef volatile u_int8_t _spinlock_lock_t;
+
+#define _SPINLOCK_LOCKED 0x80
+#define _SPINLOCK_UNLOCKED 0x00
+
+#endif /* !_SH_SPINLOCK_H_ */
diff --git a/sys/arch/sh/include/stdarg.h b/sys/arch/sh/include/stdarg.h
new file mode 100644
index 00000000000..b6a7a3f7f88
--- /dev/null
+++ b/sys/arch/sh/include/stdarg.h
@@ -0,0 +1,60 @@
+/* $OpenBSD: stdarg.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: stdarg.h,v 1.9 2006/05/21 22:39:04 uwe Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)stdarg.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _SH_STDARG_H_
+#define _SH_STDARG_H_
+
+#include <sys/cdefs.h>
+#include <machine/_types.h>
+
+typedef __va_list va_list;
+
+#ifdef __lint__
+#define __builtin_next_arg(t) ((t) ? 0 : 0)
+#define __builtin_stdarg_start(a, l) ((a) = ((l) ? 0 : 0))
+#define __builtin_va_arg(a, t) ((t)((a) ? 0 : 0))
+#define __builtin_va_end /* nothing */
+#define __builtin_va_copy(d, s) ((d) = (s))
+#endif
+
+#define va_start(ap, last) __builtin_stdarg_start((ap), (last))
+#define va_arg __builtin_va_arg
+#define va_end __builtin_va_end
+#define __va_copy(dest, src) __builtin_va_copy((dest), (src))
+
+#if __ISO_C_VISIBLE >= 1999
+#define va_copy(dest, src) __va_copy((dest), (src))
+#endif
+
+#endif /* !_SH_STDARG_H_ */
diff --git a/sys/arch/sh/include/tmureg.h b/sys/arch/sh/include/tmureg.h
new file mode 100644
index 00000000000..959957bd8f2
--- /dev/null
+++ b/sys/arch/sh/include/tmureg.h
@@ -0,0 +1,115 @@
+/* $OpenBSD: tmureg.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: tmureg.h,v 1.11 2006/03/04 01:55:03 uwe Exp $ */
+
+/*-
+ * Copyright (C) 1999 SAITOH Masanobu. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SH_TMUREG_H_
+#define _SH_TMUREG_H_
+#include <sh/devreg.h>
+
+/*
+ * TMU
+ */
+#define SH3_TOCR 0xfffffe90
+#define SH3_TSTR 0xfffffe92
+#define SH3_TCOR0 0xfffffe94
+#define SH3_TCNT0 0xfffffe98
+#define SH3_TCR0 0xfffffe9c
+#define SH3_TCOR1 0xfffffea0
+#define SH3_TCNT1 0xfffffea4
+#define SH3_TCR1 0xfffffea8
+#define SH3_TCOR2 0xfffffeac
+#define SH3_TCNT2 0xfffffeb0
+#define SH3_TCR2 0xfffffeb4
+#define SH3_TCPR2 0xfffffeb8
+
+#define SH4_TOCR 0xffd80000
+#define SH4_TSTR 0xffd80004
+#define SH4_TCOR0 0xffd80008
+#define SH4_TCNT0 0xffd8000c
+#define SH4_TCR0 0xffd80010
+#define SH4_TCOR1 0xffd80014
+#define SH4_TCNT1 0xffd80018
+#define SH4_TCR1 0xffd8001c
+#define SH4_TCOR2 0xffd80020
+#define SH4_TCNT2 0xffd80024
+#define SH4_TCR2 0xffd80028
+#define SH4_TCPR2 0xffd8002c
+#define SH4_TSTR2 0xfe100004
+#define SH4_TCOR3 0xfe100008
+#define SH4_TCNT3 0xfe10000c
+#define SH4_TCR3 0xfe100010
+#define SH4_TCOR4 0xfe100014
+#define SH4_TCNT4 0xfe100018
+#define SH4_TCR4 0xfe10001c
+
+
+#define TOCR_TCOE 0x01
+#define TSTR_STR2 0x04
+#define TSTR_STR1 0x02
+#define TSTR_STR0 0x01
+#define TCR_ICPF 0x0200
+#define TCR_UNF 0x0100
+#define TCR_ICPE1 0x0080
+#define TCR_ICPE0 0x0040
+#define TCR_UNIE 0x0020
+#define TCR_CKEG1 0x0010
+#define TCR_CKEG0 0x0008
+#define TCR_TPSC2 0x0004
+#define TCR_TPSC1 0x0002
+#define TCR_TPSC0 0x0001
+#define TCR_TPSC_P4 0x0000
+#define TCR_TPSC_P16 0x0001
+#define TCR_TPSC_P64 0x0002
+#define TCR_TPSC_P256 0x0003
+#define SH3_TCR_TPSC_RTC 0x0004
+#define SH3_TCR_TPSC_TCLK 0x0005
+#define SH4_TCR_TPSC_P1024 0x0004
+#define SH4_TCR_TPSC_RTC 0x0006
+#define SH4_TCR_TPSC_TCLK 0x0007
+#define SH4_TSTR2_STR4 0x02
+#define SH4_TSTR2_STR3 0x01
+
+
+#ifndef _LOCORE
+#if defined(SH3) && defined(SH4)
+extern uint32_t __sh_TOCR;
+extern uint32_t __sh_TSTR;
+extern uint32_t __sh_TCOR0;
+extern uint32_t __sh_TCNT0;
+extern uint32_t __sh_TCR0;
+extern uint32_t __sh_TCOR1;
+extern uint32_t __sh_TCNT1;
+extern uint32_t __sh_TCR1;
+extern uint32_t __sh_TCOR2;
+extern uint32_t __sh_TCNT2;
+extern uint32_t __sh_TCR2;
+extern uint32_t __sh_TCPR2;
+#endif /* SH3 && SH4 */
+#endif /* !_LOCORE */
+
+#endif /* !_SH_TMUREG_H_ */
diff --git a/sys/arch/sh/include/trap.h b/sys/arch/sh/include/trap.h
new file mode 100644
index 00000000000..b3a4bca347b
--- /dev/null
+++ b/sys/arch/sh/include/trap.h
@@ -0,0 +1,187 @@
+/* $OpenBSD: trap.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: exception.h,v 1.9 2006/07/22 21:58:29 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ */
+
+#ifndef _SH_EXCEPTION_H_
+#define _SH_EXCEPTION_H_
+/*
+ * SH3/SH4 Exception handling.
+ */
+#include <sh/devreg.h>
+
+#ifdef _KERNEL
+#define SH3_TRA 0xffffffd0 /* 32bit */
+#define SH3_EXPEVT 0xffffffd4 /* 32bit */
+#define SH3_INTEVT 0xffffffd8 /* 32bit */
+#define SH7709_INTEVT2 0xa4000000 /* 32bit */
+
+#define SH4_TRA 0xff000020 /* 32bit */
+#define SH4_EXPEVT 0xff000024 /* 32bit */
+#define SH4_INTEVT 0xff000028 /* 32bit */
+
+/*
+ * EXPEVT
+ */
+/* Reset exception */
+#define EXPEVT_RESET_POWER 0x000 /* Power-On reset */
+#define EXPEVT_RESET_MANUAL 0x020 /* Manual reset */
+#define EXPEVT_RESET_TLB_MULTI_HIT 0x140 /* SH4 only */
+
+/* General exception */
+#define EXPEVT_TLB_MISS_LD 0x040 /* TLB miss (load) */
+#define EXPEVT_TLB_MISS_ST 0x060 /* TLB miss (store) */
+#define EXPEVT_TLB_MOD 0x080 /* Initial page write */
+#define EXPEVT_TLB_PROT_LD 0x0a0 /* Protection violation (load) */
+#define EXPEVT_TLB_PROT_ST 0x0c0 /* Protection violation (store)*/
+#define EXPEVT_ADDR_ERR_LD 0x0e0 /* Address error (load) */
+#define EXPEVT_ADDR_ERR_ST 0x100 /* Address error (store) */
+#define EXPEVT_FPU 0x120 /* FPU exception */
+#define EXPEVT_TRAPA 0x160 /* Unconditional trap (TRAPA) */
+#define EXPEVT_RES_INST 0x180 /* Illegal instruction */
+#define EXPEVT_SLOT_INST 0x1a0 /* Illegal slot instruction */
+#define EXPEVT_BREAK 0x1e0 /* User break */
+#define EXPEVT_FPU_DISABLE 0x800 /* FPU disabled */
+#define EXPEVT_FPU_SLOT_DISABLE 0x820 /* Slot FPU disabled */
+
+/* Software bit */
+#define EXP_USER 0x001 /* exception from user-mode */
+
+#define _SH_TRA_SYSCALL 0x80 /* syscall trapa number */
+#define _SH_TRA_BREAK 0xc3 /* magic number for debugger */
+
+/*
+ * INTEVT/INTEVT2
+ */
+/* External interrupt */
+#define SH_INTEVT_NMI 0x1c0
+
+#define SH_INTEVT_TMU0_TUNI0 0x400
+#define SH_INTEVT_TMU1_TUNI1 0x420
+#define SH_INTEVT_TMU2_TUNI2 0x440
+#define SH_INTEVT_TMU2_TICPI2 0x460
+
+#define SH_INTEVT_SCI_ERI 0x4e0
+#define SH_INTEVT_SCI_RXI 0x500
+#define SH_INTEVT_SCI_TXI 0x520
+#define SH_INTEVT_SCI_TEI 0x540
+
+#define SH_INTEVT_WDT_ITI 0x560
+
+#define SH_INTEVT_IRL9 0x320
+#define SH_INTEVT_IRL11 0x360
+#define SH_INTEVT_IRL13 0x3a0
+
+#define SH4_INTEVT_SCIF_ERI 0x700
+#define SH4_INTEVT_SCIF_RXI 0x720
+#define SH4_INTEVT_SCIF_BRI 0x740
+#define SH4_INTEVT_SCIF_TXI 0x760
+
+#define SH7709_INTEVT2_IRQ0 0x600
+#define SH7709_INTEVT2_IRQ1 0x620
+#define SH7709_INTEVT2_IRQ2 0x640
+#define SH7709_INTEVT2_IRQ3 0x660
+#define SH7709_INTEVT2_IRQ4 0x680
+#define SH7709_INTEVT2_IRQ5 0x6a0
+
+#define SH7709_INTEVT2_PINT07 0x700
+#define SH7709_INTEVT2_PINT8F 0x720
+
+#define SH7709_INTEVT2_DEI0 0x800
+#define SH7709_INTEVT2_DEI1 0x820
+#define SH7709_INTEVT2_DEI2 0x840
+#define SH7709_INTEVT2_DEI3 0x860
+
+#define SH7709_INTEVT2_IRDA_ERI 0x880
+#define SH7709_INTEVT2_IRDA_RXI 0x8a0
+#define SH7709_INTEVT2_IRDA_BRI 0x8c0
+#define SH7709_INTEVT2_IRDA_TXI 0x8e0
+
+#define SH7709_INTEVT2_SCIF_ERI 0x900
+#define SH7709_INTEVT2_SCIF_RXI 0x920
+#define SH7709_INTEVT2_SCIF_BRI 0x940
+#define SH7709_INTEVT2_SCIF_TXI 0x960
+
+#define SH7709_INTEVT2_ADC 0x980
+
+/* SH7750R, SH7751, SH7751R */
+#define SH4_INTEVT_IRL0 0x240
+#define SH4_INTEVT_IRL1 0x2a0
+#define SH4_INTEVT_IRL2 0x300
+#define SH4_INTEVT_IRL3 0x360
+
+#define SH4_INTEVT_IRQ0 0x200
+#define SH4_INTEVT_IRQ1 0x220
+#define SH4_INTEVT_IRQ2 0x240
+#define SH4_INTEVT_IRQ3 0x260
+#define SH4_INTEVT_IRQ4 0x280
+#define SH4_INTEVT_IRQ5 0x2a0
+#define SH4_INTEVT_IRQ6 0x2c0
+#define SH4_INTEVT_IRQ7 0x2e0
+#define SH4_INTEVT_IRQ8 0x300
+#define SH4_INTEVT_IRQ9 0x320
+#define SH4_INTEVT_IRQ10 0x340
+#define SH4_INTEVT_IRQ11 0x360
+#define SH4_INTEVT_IRQ12 0x380
+#define SH4_INTEVT_IRQ13 0x3a0
+#define SH4_INTEVT_IRQ14 0x3c0
+#define SH4_INTEVT_IRQ15 0x3e0
+
+#define SH4_INTEVT_TMU3 0xb00
+#define SH4_INTEVT_TMU4 0xb80
+
+#define SH4_INTEVT_PCISERR 0xa00
+#define SH4_INTEVT_PCIERR 0xae0
+#define SH4_INTEVT_PCIPWDWN 0xac0
+#define SH4_INTEVT_PCIPWON 0xaa0
+#define SH4_INTEVT_PCIDMA0 0xa80
+#define SH4_INTEVT_PCIDMA1 0xa60
+#define SH4_INTEVT_PCIDMA2 0xa40
+#define SH4_INTEVT_PCIDMA3 0xa20
+
+#ifndef _LOCORE
+
+#if defined(SH3) && defined(SH4)
+extern uint32_t __sh_TRA;
+extern uint32_t __sh_EXPEVT;
+extern uint32_t __sh_INTEVT;
+#endif /* SH3 && SH4 */
+
+extern const char * const exp_type[];
+extern const int exp_types;
+
+#endif /* !_LOCORE */
+
+#endif /* _KERNEL */
+#endif /* !_SH_EXCEPTION_H_ */
diff --git a/sys/arch/sh/include/ubcreg.h b/sys/arch/sh/include/ubcreg.h
new file mode 100644
index 00000000000..dacbfa52f1d
--- /dev/null
+++ b/sys/arch/sh/include/ubcreg.h
@@ -0,0 +1,86 @@
+/* $OpenBSD: ubcreg.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: ubcreg.h,v 1.4 2006/03/04 01:55:03 uwe Exp $ */
+
+/*-
+ * Copyright (C) 1999 SAITOH Masanobu. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SH_UBCREG_H_
+#define _SH_UBCREG_H_
+#include <sh/devreg.h>
+
+/*
+ * User Break Controller
+ */
+
+/* ch-A */
+#define SH3_BARA 0xffffffb0
+#define SH3_BAMRA 0xffffffb4
+#define SH3_BASRA 0xffffffe4
+#define SH3_BBRA 0xffffffb8
+/* ch-B */
+#define SH3_BARB 0xffffffa0
+#define SH3_BAMRB 0xffffffa4
+#define SH3_BASRB 0xffffffe8
+#define SH3_BBRB 0xffffffa8
+#define SH3_BDRB 0xffffff90
+#define SH3_BDMRB 0xffffff94
+/* common */
+#define SH3_BRCR 0xffffff98
+
+
+/* ch-A */
+#define SH4_BARA 0xff200000
+#define SH4_BAMRA 0xff200004
+#define SH4_BASRA 0xff000014
+#define SH4_BBRA 0xff200008
+
+/* ch-B */
+#define SH4_BARB 0xff20000c
+#define SH4_BAMRB 0xff200010
+#define SH4_BASRB 0xff000018
+#define SH4_BBRB 0xff200014
+#define SH4_BDRB 0xff200018
+#define SH4_BDMRB 0xff20001c
+/* common */
+#define SH4_BRCR 0xff200020
+
+#ifndef _LOCORE
+#if defined(SH3) && defined(SH4)
+extern uint32_t __sh_BARA;
+extern uint32_t __sh_BAMRA;
+extern uint32_t __sh_BASRA;
+extern uint32_t __sh_BBRA;
+extern uint32_t __sh_BARB;
+extern uint32_t __sh_BAMRB;
+extern uint32_t __sh_BASRB;
+extern uint32_t __sh_BBRB;
+extern uint32_t __sh_BDRB;
+extern uint32_t __sh_BDMRB;
+extern uint32_t __sh_BRCR;
+#endif /* SH3 && SH4 */
+#endif /* !_LOCORE */
+
+#endif /* !_SH_UBCREG_H_ */
diff --git a/sys/arch/sh/include/userret.h b/sys/arch/sh/include/userret.h
new file mode 100644
index 00000000000..07db83959a2
--- /dev/null
+++ b/sys/arch/sh/include/userret.h
@@ -0,0 +1,94 @@
+/* $OpenBSD: userret.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: userret.h,v 1.9 2006/02/16 20:17:15 perry Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department and Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Utah Hdr: trap.c 1.32 91/04/06
+ *
+ * @(#)trap.c 8.5 (Berkeley) 1/11/94
+ */
+/*
+ * Copyright (c) 1988 University of Utah.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department and Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Utah Hdr: trap.c 1.32 91/04/06
+ *
+ * @(#)trap.c 8.5 (Berkeley) 1/11/94
+ */
+
+#include <sys/signalvar.h>
+#include <machine/cpu.h>
+
+static __inline void userret(struct proc *);
+
+static __inline void
+userret(struct proc *p)
+{
+ int sig;
+
+ while ((sig = CURSIG(p)) != 0)
+ postsig(sig);
+
+ curpriority = p->p_priority = p->p_usrpri;
+}
diff --git a/sys/arch/sh/include/varargs.h b/sys/arch/sh/include/varargs.h
new file mode 100644
index 00000000000..6fae10957e0
--- /dev/null
+++ b/sys/arch/sh/include/varargs.h
@@ -0,0 +1,57 @@
+/* $OpenBSD: varargs.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: varargs.h,v 1.7 2006/05/21 22:39:04 uwe Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)varargs.h 8.2 (Berkeley) 3/22/94
+ */
+
+#ifndef _SH_VARARGS_H_
+#define _SH_VARARGS_H_
+
+#include <machine/stdarg.h>
+
+#if __GNUC__ == 1
+#define __va_ellipsis
+#else
+#define __va_ellipsis ...
+#endif
+
+#define va_alist __builtin_va_alist
+#define va_dcl __builtin_va_alist_t __builtin_va_alist; __va_ellipsis
+
+#undef va_start
+#define va_start(ap) __builtin_varargs_start((ap))
+
+#endif /* !_SH_VARARGS_H_ */
diff --git a/sys/arch/sh/include/vmparam.h b/sys/arch/sh/include/vmparam.h
new file mode 100644
index 00000000000..c9bf886ac4d
--- /dev/null
+++ b/sys/arch/sh/include/vmparam.h
@@ -0,0 +1,107 @@
+/* $OpenBSD: vmparam.h,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: vmparam.h,v 1.17 2006/03/04 01:55:03 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#ifndef _SH_VMPARAM_H_
+#define _SH_VMPARAM_H_
+#include <sys/queue.h>
+
+/* Virtual address map. */
+#define VM_MIN_ADDRESS ((vaddr_t)0)
+#define VM_MAXUSER_ADDRESS ((vaddr_t)0x7ffff000)
+#define VM_MAX_ADDRESS ((vaddr_t)0x7ffff000)
+#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)0xc0000000)
+#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)0xe0000000)
+
+/* top of stack */
+#define USRSTACK VM_MAXUSER_ADDRESS
+
+/* Virtual memory resoruce limit. */
+#define MAXTSIZ (64 * 1024 * 1024) /* max text size */
+#ifndef MAXDSIZ
+#define MAXDSIZ (512 * 1024 * 1024) /* max data size */
+#endif
+#ifndef MAXSSIZ
+#define MAXSSIZ (32 * 1024 * 1024) /* max stack size */
+#endif
+
+/* initial data size limit */
+#ifndef DFLDSIZ
+#define DFLDSIZ (128 * 1024 * 1024)
+#endif
+/* initial stack size limit */
+#ifndef DFLSSIZ
+#define DFLSSIZ (2 * 1024 * 1024)
+#endif
+
+#define STACKGAP_RANDOM (256 * 1024)
+
+/*
+ * Size of shared memory map
+ */
+#ifndef SHMMAXPGS
+#define SHMMAXPGS 1024
+#endif
+
+/* Size of user raw I/O map */
+#ifndef USRIOSIZE
+#define USRIOSIZE (MAXBSIZE / PAGE_SIZE * 8)
+#endif
+
+#define VM_PHYS_SIZE (USRIOSIZE * PAGE_SIZE)
+
+/* pmap-specific data store in the vm_page structure. */
+#define __HAVE_VM_PAGE_MD
+#define PVH_REFERENCED 1
+#define PVH_MODIFIED 2
+
+#ifndef _LOCORE
+struct pv_entry;
+struct vm_page_md {
+ SLIST_HEAD(, pv_entry) pvh_head;
+ int pvh_flags;
+};
+
+#define VM_MDPAGE_INIT(pg) \
+do { \
+ struct vm_page_md *pvh = &(pg)->mdpage; \
+ SLIST_INIT(&pvh->pvh_head); \
+ pvh->pvh_flags = 0; \
+} while (/*CONSTCOND*/0)
+#endif /* _LOCORE */
+#endif /* !_SH_VMPARAM_H_ */
diff --git a/sys/arch/sh/sh/cache.c b/sys/arch/sh/sh/cache.c
new file mode 100644
index 00000000000..53939b37376
--- /dev/null
+++ b/sys/arch/sh/sh/cache.c
@@ -0,0 +1,173 @@
+/* $OpenBSD: cache.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: cache.c,v 1.11 2006/01/02 23:37:34 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sh/cache.h>
+#include <sh/cache_sh3.h>
+#include <sh/cache_sh4.h>
+
+/*
+ * __cache_flush is used before sh_cache_config() is called.
+ */
+static void __cache_flush(void);
+
+struct sh_cache_ops sh_cache_ops = {
+ ._icache_sync_all = (void (*)(void))__cache_flush,
+ ._icache_sync_range = (void (*)(vaddr_t, vsize_t))__cache_flush,
+ ._icache_sync_range_index = (void (*)(vaddr_t, vsize_t))__cache_flush,
+ ._dcache_wbinv_all = (void (*)(void))__cache_flush,
+ ._dcache_wbinv_range = (void (*)(vaddr_t, vsize_t))__cache_flush,
+ ._dcache_wbinv_range_index = (void (*)(vaddr_t, vsize_t))__cache_flush,
+ ._dcache_inv_range = (void (*)(vaddr_t, vsize_t))__cache_flush,
+ ._dcache_wb_range = (void (*)(vaddr_t, vsize_t))__cache_flush
+};
+
+int sh_cache_enable_icache;
+int sh_cache_enable_dcache;
+int sh_cache_write_through;
+int sh_cache_write_through_p0_u0_p3;
+int sh_cache_write_through_p1;
+int sh_cache_unified;
+int sh_cache_ways;
+int sh_cache_size_icache;
+int sh_cache_size_dcache;
+int sh_cache_line_size;
+int sh_cache_ram_mode;
+int sh_cache_index_mode_icache;
+int sh_cache_index_mode_dcache;
+
+void
+sh_cache_init()
+{
+#ifdef CACHE_DEBUG
+ return;
+#endif
+#ifdef SH3
+ if (CPU_IS_SH3)
+ sh3_cache_config();
+#endif
+#ifdef SH4
+ if (CPU_IS_SH4)
+ sh4_cache_config();
+#endif
+}
+
+void
+sh_cache_information()
+{
+#ifdef CACHE_DEBUG
+ printf("*** USE CPU INDEPENDENT CACHE OPS. ***\n");
+ return;
+#endif
+
+ /* I-cache or I/D-unified cache */
+ printf("cpu0: %dKB/%dB",
+ sh_cache_size_icache >> 10, sh_cache_line_size);
+ if (sh_cache_ways > 1)
+ printf(" %d-way set-associative", sh_cache_ways);
+ else
+ printf(" direct-mapped");
+ if (sh_cache_unified)
+ printf(" I/D-unified");
+ else
+ printf(" Instruction");
+ printf(" cache.");
+ if (!sh_cache_enable_icache)
+ printf(" DISABLED");
+ if (sh_cache_unified && sh_cache_ram_mode)
+ printf(" RAM-mode");
+ if (sh_cache_index_mode_icache)
+ printf(" INDEX-mode");
+ printf("\n");
+
+ /* D-cache */
+ if (!sh_cache_unified) {
+ printf("cpu0: %dKB/%dB", sh_cache_size_dcache >> 10,
+ sh_cache_line_size);
+ if (sh_cache_ways > 1)
+ printf(" %d-way set-associative", sh_cache_ways);
+ else
+ printf(" direct-mapped");
+ printf(" Data cache.");
+ if (!sh_cache_enable_dcache)
+ printf(" DISABLED");
+ if (sh_cache_ram_mode)
+ printf(" RAM-mode");
+ if (sh_cache_index_mode_dcache)
+ printf(" INDEX-mode");
+ printf("\n");
+ }
+
+ /* Write-through/back */
+ printf("cpu0: P0, U0, P3 write-%s; P1 write-%s\n",
+ sh_cache_write_through_p0_u0_p3 ? "through" : "back",
+ sh_cache_write_through_p1 ? "through" : "back");
+}
+
+/*
+ * CPU-independent cache flush.
+ */
+void
+__cache_flush()
+{
+ volatile int *p = (int *)SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN);
+ int i;
+ int d;
+
+ /* Flush D-Cache */
+ /*
+ * Access address range [13:4].
+ * max:
+ * 16KB line-size 16B 4-way ... [11:4] * 4
+ * 16KB line-size 32B 1-way ... [13:5]
+ */
+ for (i = 0; i < 256/*entry*/ * 4/*way*/; i++) {
+ d = *p;
+ p += 4; /* next line index (16B) */
+ }
+
+ /* Flush I-Cache */
+ /*
+ * this code flush I-cache. but can't compile..
+ * __asm volatile(".space 8192");
+ *
+ */
+}
diff --git a/sys/arch/sh/sh/cache_sh3.c b/sys/arch/sh/sh/cache_sh3.c
new file mode 100644
index 00000000000..af31deb58a7
--- /dev/null
+++ b/sys/arch/sh/sh/cache_sh3.c
@@ -0,0 +1,246 @@
+/* $OpenBSD: cache_sh3.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: cache_sh3.c,v 1.12 2006/03/04 01:13:35 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sh/cache.h>
+#include <sh/cache_sh3.h>
+
+#define round_line(x) (((x) + 15) & ~15)
+#define trunc_line(x) ((x) & ~15)
+
+void sh3_cache_wbinv_all(void);
+void sh3_cache_wbinv_range(vaddr_t, vsize_t);
+void sh3_cache_wbinv_range_index(vaddr_t, vsize_t);
+void sh3_cache_panic(vaddr_t, vsize_t);
+void sh3_cache_nop(vaddr_t, vsize_t);
+
+int sh_cache_way_size;
+int sh_cache_way_shift;
+int sh_cache_entry_mask;
+
+static inline void cache_sh3_op_line_16_nway(int, vaddr_t, uint32_t);
+static inline void cache_sh3_op_8lines_16_nway(int, vaddr_t, uint32_t);
+
+void
+sh3_cache_config()
+{
+ size_t cache_size;
+ uint32_t r;
+
+ /* Determine cache size */
+ switch (cpu_product) {
+ default:
+ /* FALLTHROUGH */
+ case CPU_PRODUCT_7708:
+ /* FALLTHROUGH */
+ case CPU_PRODUCT_7708S:
+ /* FALLTHROUGH */
+ case CPU_PRODUCT_7708R:
+ cache_size = 8 * 1024;
+ break;
+ case CPU_PRODUCT_7709:
+ cache_size = 8 * 1024;
+ break;
+ case CPU_PRODUCT_7709A:
+ cache_size = 16 * 1024;
+ break;
+ }
+
+ r = _reg_read_4(SH3_CCR);
+
+ sh_cache_unified = 1;
+ sh_cache_enable_unified = (r & SH3_CCR_CE);
+ sh_cache_line_size = 16;
+ sh_cache_write_through_p0_u0_p3 = r & SH3_CCR_WT;
+ sh_cache_write_through_p1 = !(r & SH3_CCR_CB);
+ sh_cache_write_through = sh_cache_write_through_p0_u0_p3 &&
+ sh_cache_write_through_p1;
+
+ sh_cache_ram_mode = r & SH3_CCR_RA;
+ if (sh_cache_ram_mode) {
+ /*
+ * In RAM-mode, way 2 and 3 are used as RAM.
+ */
+ sh_cache_ways = 2;
+ sh_cache_size_unified = cache_size / 2;
+ } else {
+ sh_cache_ways = 4;
+ sh_cache_size_unified = cache_size;
+ }
+
+ /* size enough to access foreach entries */
+ sh_cache_way_size = sh_cache_size_unified / 4/*way*/;
+ /* mask for extracting entry select */
+ sh_cache_entry_mask = (sh_cache_way_size - 1) & ~15/*line-mask*/;
+ /* shift for way selection (16KB/8KB) */
+ sh_cache_way_shift =
+ /* entry bits */
+ ffs(sh_cache_size_unified / (4/*way*/ * 16/*line-size*/)) - 1
+ /* line bits */
+ + 4;
+
+ sh_cache_ops._icache_sync_all = sh3_cache_wbinv_all;
+ sh_cache_ops._icache_sync_range = sh3_cache_wbinv_range;
+ sh_cache_ops._icache_sync_range_index = sh3_cache_wbinv_range_index;
+ sh_cache_ops._dcache_wbinv_all = sh3_cache_wbinv_all;
+ sh_cache_ops._dcache_wbinv_range = sh3_cache_wbinv_range;
+ sh_cache_ops._dcache_wbinv_range_index = sh3_cache_wbinv_range_index;
+ /* SH3 can't invalidate without write-back */
+ sh_cache_ops._dcache_inv_range = sh3_cache_panic;
+ if (sh_cache_write_through) {
+ sh_cache_ops._dcache_wb_range = sh3_cache_nop;
+ } else {
+ /* SH3 can't write-back without invalidate */
+ sh_cache_ops._dcache_wb_range = sh3_cache_wbinv_range;
+ }
+}
+
+/*
+ * cache_sh3_op_line_16_nway: (index-operation)
+ *
+ * Clear the specified bits on single 16-byte cache line. n-ways.
+ *
+ */
+static inline void
+cache_sh3_op_line_16_nway(int n, vaddr_t va, uint32_t bits)
+{
+ vaddr_t cca;
+ int way;
+
+ /* extract entry # */
+ va &= sh_cache_entry_mask;
+
+ /* operate for each way */
+ for (way = 0; way < n; way++) {
+ cca = (SH3_CCA | way << sh_cache_way_shift | va);
+ _reg_bclr_4(cca, bits);
+ }
+}
+
+/*
+ * cache_sh3_op_8lines_16_nway: (index-operation)
+ *
+ * Clear the specified bits on 8 16-byte cache lines, n-ways.
+ *
+ */
+static inline void
+cache_sh3_op_8lines_16_nway(int n, vaddr_t va, uint32_t bits)
+{
+ volatile uint32_t *cca;
+ int way;
+
+ /* extract entry # */
+ va &= sh_cache_entry_mask;
+
+ /* operate for each way */
+ for (way = 0; way < n; way++) {
+ cca = (volatile uint32_t *)
+ (SH3_CCA | way << sh_cache_way_shift | va);
+ cca[ 0] &= ~bits;
+ cca[ 4] &= ~bits;
+ cca[ 8] &= ~bits;
+ cca[12] &= ~bits;
+ cca[16] &= ~bits;
+ cca[20] &= ~bits;
+ cca[24] &= ~bits;
+ cca[28] &= ~bits;
+ }
+}
+
+void
+sh3_cache_wbinv_all()
+{
+ vaddr_t va;
+
+ for (va = 0; va < sh_cache_way_size; va += 16 * 8)
+ cache_sh3_op_8lines_16_nway(sh_cache_ways, va, CCA_U | CCA_V);
+}
+
+void
+sh3_cache_wbinv_range_index(vaddr_t va, vsize_t sz)
+{
+ vaddr_t eva = round_line(va + sz);
+
+ va = trunc_line(va);
+
+ while ((eva - va) >= (8 * 16)) {
+ cache_sh3_op_8lines_16_nway(sh_cache_ways, va, CCA_U | CCA_V);
+ va += 16 * 8;
+ }
+
+ while (va < eva) {
+ cache_sh3_op_line_16_nway(sh_cache_ways, va, CCA_U | CCA_V);
+ va += 16;
+ }
+}
+
+void
+sh3_cache_wbinv_range(vaddr_t va, vsize_t sz)
+{
+ vaddr_t eva = round_line(va + sz);
+ vaddr_t cca;
+
+ va = trunc_line(va);
+
+ while (va < eva) {
+ cca = SH3_CCA | CCA_A | (va & sh_cache_entry_mask);
+ /*
+ * extract virtual tag-address.
+ * MMU translates it to physical address tag,
+ * and write to address-array.
+ * implicitly specified U = 0, V = 0.
+ */
+ _reg_write_4(cca, va & CCA_TAGADDR_MASK);
+ va += 16;
+ }
+}
+
+void
+sh3_cache_panic(vaddr_t va, vsize_t size)
+{
+ panic("SH3 can't invalidate without write-back");
+}
+
+void
+sh3_cache_nop(vaddr_t va, vsize_t sz)
+{
+ /* NO-OP */
+}
diff --git a/sys/arch/sh/sh/cache_sh4.c b/sys/arch/sh/sh/cache_sh4.c
new file mode 100644
index 00000000000..2f0a0fc9453
--- /dev/null
+++ b/sys/arch/sh/sh/cache_sh4.c
@@ -0,0 +1,470 @@
+/* $OpenBSD: cache_sh4.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: cache_sh4.c,v 1.15 2005/12/24 23:24:02 perry Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sh/cache.h>
+#include <sh/cache_sh4.h>
+
+#define round_line(x) (((x) + 31) & ~31)
+#define trunc_line(x) ((x) & ~31)
+
+void sh4_icache_sync_all(void);
+void sh4_icache_sync_range(vaddr_t, vsize_t);
+void sh4_icache_sync_range_index(vaddr_t, vsize_t);
+void sh4_dcache_wbinv_all(void);
+void sh4_dcache_wbinv_range(vaddr_t, vsize_t);
+void sh4_dcache_wbinv_range_index(vaddr_t, vsize_t);
+void sh4_dcache_inv_range(vaddr_t, vsize_t);
+void sh4_dcache_wb_range(vaddr_t, vsize_t);
+
+/* EMODE */
+void sh4_emode_icache_sync_all(void);
+void sh4_emode_icache_sync_range_index(vaddr_t, vsize_t);
+void sh4_emode_dcache_wbinv_all(void);
+void sh4_emode_dcache_wbinv_range_index(vaddr_t, vsize_t);
+
+/* must be inlined. */
+static inline void cache_sh4_op_line_32(vaddr_t, vaddr_t, uint32_t,
+ uint32_t);
+static inline void cache_sh4_op_8lines_32(vaddr_t, vaddr_t, uint32_t,
+ uint32_t);
+static inline void cache_sh4_emode_op_line_32(vaddr_t, vaddr_t,
+ uint32_t, uint32_t, uint32_t);
+static inline void cache_sh4_emode_op_8lines_32(vaddr_t, vaddr_t,
+ uint32_t, uint32_t, uint32_t);
+
+void
+sh4_cache_config(void)
+{
+ int icache_size;
+ int dcache_size;
+ int ways;
+ uint32_t r;
+
+ /* Determine cache size */
+ switch (cpu_product) {
+ default:
+ /* FALLTHROUGH */
+ case CPU_PRODUCT_7750:
+ case CPU_PRODUCT_7750S:
+ case CPU_PRODUCT_7751:
+#if defined(SH4_CACHE_DISABLE_EMODE)
+ case CPU_PRODUCT_7750R:
+ case CPU_PRODUCT_7751R:
+#endif
+ icache_size = SH4_ICACHE_SIZE;
+ dcache_size = SH4_DCACHE_SIZE;
+ ways = 1;
+ r = SH4_CCR_ICE|SH4_CCR_OCE|SH4_CCR_WT;
+ break;
+
+#if !defined(SH4_CACHE_DISABLE_EMODE)
+ case CPU_PRODUCT_7750R:
+ case CPU_PRODUCT_7751R:
+ icache_size = SH4_EMODE_ICACHE_SIZE;
+ dcache_size = SH4_EMODE_DCACHE_SIZE;
+ ways = 2;
+ r = SH4_CCR_EMODE|SH4_CCR_ICE|SH4_CCR_OCE|SH4_CCR_WT;
+ break;
+#endif
+ }
+#if defined(SH4_CACHE_DISABLE_ICACHE)
+ r &= ~SH4_CCR_ICE;
+#endif
+#if defined(SH4_CACHE_DISABLE_DCACHE)
+ r &= ~SH4_CCR_OCE;
+#endif
+#if defined(SH4_CACHE_WB_U0_P0_P3)
+ r &= ~SH4_CCR_WT;
+#endif
+#if defined(SH4_CACHE_WB_P1)
+ r |= SH4_CCR_CB;
+#endif
+
+ sh4_icache_sync_all();
+ RUN_P2;
+ _reg_write_4(SH4_CCR, SH4_CCR_ICI|SH4_CCR_OCI);
+ _reg_write_4(SH4_CCR, r);
+ RUN_P1;
+
+ r = _reg_read_4(SH4_CCR);
+
+ sh_cache_unified = 0;
+ sh_cache_enable_icache = (r & SH4_CCR_ICE);
+ sh_cache_enable_dcache = (r & SH4_CCR_OCE);
+ sh_cache_ways = ways;
+ sh_cache_line_size = SH4_CACHE_LINESZ;
+ sh_cache_write_through_p0_u0_p3 = (r & SH4_CCR_WT);
+ sh_cache_write_through_p1 = !(r & SH4_CCR_CB);
+ sh_cache_write_through = sh_cache_write_through_p0_u0_p3 &&
+ sh_cache_write_through_p1;
+ sh_cache_ram_mode = (r & SH4_CCR_ORA);
+ sh_cache_index_mode_icache = (r & SH4_CCR_IIX);
+ sh_cache_index_mode_dcache = (r & SH4_CCR_OIX);
+
+ sh_cache_size_dcache = dcache_size;
+ if (sh_cache_ram_mode)
+ sh_cache_size_dcache /= 2;
+ sh_cache_size_icache = icache_size;
+
+ sh_cache_ops._icache_sync_all = sh4_icache_sync_all;
+ sh_cache_ops._icache_sync_range = sh4_icache_sync_range;
+ sh_cache_ops._icache_sync_range_index = sh4_icache_sync_range_index;
+
+ sh_cache_ops._dcache_wbinv_all = sh4_dcache_wbinv_all;
+ sh_cache_ops._dcache_wbinv_range = sh4_dcache_wbinv_range;
+ sh_cache_ops._dcache_wbinv_range_index = sh4_dcache_wbinv_range_index;
+ sh_cache_ops._dcache_inv_range = sh4_dcache_inv_range;
+ sh_cache_ops._dcache_wb_range = sh4_dcache_wb_range;
+
+ switch (cpu_product) {
+ case CPU_PRODUCT_7750R:
+ case CPU_PRODUCT_7751R:
+ if (!(r & SH4_CCR_EMODE)) {
+ break;
+ }
+ sh_cache_ops._icache_sync_all = sh4_emode_icache_sync_all;
+ sh_cache_ops._icache_sync_range_index = sh4_emode_icache_sync_range_index;
+ sh_cache_ops._dcache_wbinv_all = sh4_emode_dcache_wbinv_all;
+ sh_cache_ops._dcache_wbinv_range_index = sh4_emode_dcache_wbinv_range_index;
+ break;
+ }
+}
+
+/*
+ * cache_sh4_op_line_32: (index-operation)
+ *
+ * Clear the specified bits on single 32-byte cache line.
+ */
+static inline void
+cache_sh4_op_line_32(vaddr_t va, vaddr_t base, uint32_t mask, uint32_t bits)
+{
+ vaddr_t cca;
+
+ cca = base | (va & mask);
+ _reg_bclr_4(cca, bits);
+}
+
+/*
+ * cache_sh4_op_8lines_32: (index-operation)
+ *
+ * Clear the specified bits on 8 32-byte cache lines.
+ */
+static inline void
+cache_sh4_op_8lines_32(vaddr_t va, vaddr_t base, uint32_t mask, uint32_t bits)
+{
+ volatile uint32_t *cca = (volatile uint32_t *)
+ (base | (va & mask));
+
+ cca[ 0] &= ~bits;
+ cca[ 8] &= ~bits;
+ cca[16] &= ~bits;
+ cca[24] &= ~bits;
+ cca[32] &= ~bits;
+ cca[40] &= ~bits;
+ cca[48] &= ~bits;
+ cca[56] &= ~bits;
+}
+
+void
+sh4_icache_sync_all(void)
+{
+ vaddr_t va = 0;
+ vaddr_t eva = SH4_ICACHE_SIZE;
+
+ sh4_dcache_wbinv_all();
+
+ RUN_P2;
+ while (va < eva) {
+ cache_sh4_op_8lines_32(va, SH4_CCIA, CCIA_ENTRY_MASK, CCIA_V);
+ va += 32 * 8;
+ }
+ RUN_P1;
+}
+
+void
+sh4_icache_sync_range(vaddr_t va, vsize_t sz)
+{
+ vaddr_t ccia;
+ vaddr_t eva = round_line(va + sz);
+ va = trunc_line(va);
+
+ sh4_dcache_wbinv_range(va, (eva - va));
+
+ RUN_P2;
+ while (va < eva) {
+ /* CCR.IIX has no effect on this entry specification */
+ ccia = SH4_CCIA | CCIA_A | (va & CCIA_ENTRY_MASK);
+ _reg_write_4(ccia, va & CCIA_TAGADDR_MASK); /* V = 0 */
+ va += 32;
+ }
+ RUN_P1;
+}
+
+void
+sh4_icache_sync_range_index(vaddr_t va, vsize_t sz)
+{
+ vaddr_t eva = round_line(va + sz);
+ va = trunc_line(va);
+
+ sh4_dcache_wbinv_range_index(va, eva - va);
+
+ RUN_P2;
+ while ((eva - va) >= (8 * 32)) {
+ cache_sh4_op_8lines_32(va, SH4_CCIA, CCIA_ENTRY_MASK, CCIA_V);
+ va += 32 * 8;
+ }
+
+ while (va < eva) {
+ cache_sh4_op_line_32(va, SH4_CCIA, CCIA_ENTRY_MASK, CCIA_V);
+ va += 32;
+ }
+ RUN_P1;
+}
+
+void
+sh4_dcache_wbinv_all(void)
+{
+ vaddr_t va = 0;
+ vaddr_t eva = SH4_DCACHE_SIZE;
+
+ RUN_P2;
+ while (va < eva) {
+ cache_sh4_op_8lines_32(va, SH4_CCDA, CCDA_ENTRY_MASK,
+ (CCDA_U | CCDA_V));
+ va += 32 * 8;
+ }
+ RUN_P1;
+}
+
+void
+sh4_dcache_wbinv_range(vaddr_t va, vsize_t sz)
+{
+ vaddr_t eva = round_line(va + sz);
+ va = trunc_line(va);
+
+ while (va < eva) {
+ __asm volatile("ocbp @%0" : : "r"(va));
+ va += 32;
+ }
+}
+
+void
+sh4_dcache_wbinv_range_index(vaddr_t va, vsize_t sz)
+{
+ vaddr_t eva = round_line(va + sz);
+ va = trunc_line(va);
+
+ RUN_P2;
+ while ((eva - va) >= (8 * 32)) {
+ cache_sh4_op_8lines_32(va, SH4_CCDA, CCDA_ENTRY_MASK,
+ (CCDA_U | CCDA_V));
+ va += 32 * 8;
+ }
+
+ while (va < eva) {
+ cache_sh4_op_line_32(va, SH4_CCDA, CCDA_ENTRY_MASK,
+ (CCDA_U | CCDA_V));
+ va += 32;
+ }
+ RUN_P1;
+}
+
+void
+sh4_dcache_inv_range(vaddr_t va, vsize_t sz)
+{
+ vaddr_t eva = round_line(va + sz);
+ va = trunc_line(va);
+
+ while (va < eva) {
+ __asm volatile("ocbi @%0" : : "r"(va));
+ va += 32;
+ }
+}
+
+void
+sh4_dcache_wb_range(vaddr_t va, vsize_t sz)
+{
+ vaddr_t eva = round_line(va + sz);
+ va = trunc_line(va);
+
+ while (va < eva) {
+ __asm volatile("ocbwb @%0" : : "r"(va));
+ va += 32;
+ }
+}
+
+/*
+ * EMODE operation
+ */
+/*
+ * cache_sh4_emode_op_line_32: (index-operation)
+ *
+ * Clear the specified bits on single 32-byte cache line. 2-ways.
+ */
+static inline void
+cache_sh4_emode_op_line_32(vaddr_t va, vaddr_t base, uint32_t mask,
+ uint32_t bits, uint32_t way_shift)
+{
+ vaddr_t cca;
+
+ /* extract entry # */
+ va &= mask;
+
+ /* operate for each way */
+ cca = base | (0 << way_shift) | va;
+ _reg_bclr_4(cca, bits);
+
+ cca = base | (1 << way_shift) | va;
+ _reg_bclr_4(cca, bits);
+}
+
+/*
+ * cache_sh4_emode_op_8lines_32: (index-operation)
+ *
+ * Clear the specified bits on 8 32-byte cache lines. 2-ways.
+ */
+static inline void
+cache_sh4_emode_op_8lines_32(vaddr_t va, vaddr_t base, uint32_t mask,
+ uint32_t bits, uint32_t way_shift)
+{
+ volatile uint32_t *cca;
+
+ /* extract entry # */
+ va &= mask;
+
+ /* operate for each way */
+ cca = (volatile uint32_t *)(base | (0 << way_shift) | va);
+ cca[ 0] &= ~bits;
+ cca[ 8] &= ~bits;
+ cca[16] &= ~bits;
+ cca[24] &= ~bits;
+ cca[32] &= ~bits;
+ cca[40] &= ~bits;
+ cca[48] &= ~bits;
+ cca[56] &= ~bits;
+
+ cca = (volatile uint32_t *)(base | (1 << way_shift) | va);
+ cca[ 0] &= ~bits;
+ cca[ 8] &= ~bits;
+ cca[16] &= ~bits;
+ cca[24] &= ~bits;
+ cca[32] &= ~bits;
+ cca[40] &= ~bits;
+ cca[48] &= ~bits;
+ cca[56] &= ~bits;
+}
+
+void
+sh4_emode_icache_sync_all(void)
+{
+ vaddr_t va = 0;
+ vaddr_t eva = SH4_EMODE_ICACHE_SIZE;
+
+ sh4_emode_dcache_wbinv_all();
+
+ RUN_P2;
+ while (va < eva) {
+ cache_sh4_emode_op_8lines_32(va, SH4_CCIA, CCIA_ENTRY_MASK,
+ CCIA_V, 13);
+ va += 32 * 8;
+ }
+ RUN_P1;
+}
+
+void
+sh4_emode_icache_sync_range_index(vaddr_t va, vsize_t sz)
+{
+ vaddr_t eva = round_line(va + sz);
+ va = trunc_line(va);
+
+ sh4_emode_dcache_wbinv_range_index(va, eva - va);
+
+ RUN_P2;
+ while ((eva - va) >= (8 * 32)) {
+ cache_sh4_emode_op_8lines_32(va, SH4_CCIA, CCIA_ENTRY_MASK,
+ CCIA_V, 13);
+ va += 32 * 8;
+ }
+
+ while (va < eva) {
+ cache_sh4_emode_op_line_32(va, SH4_CCIA, CCIA_ENTRY_MASK,
+ CCIA_V, 13);
+ va += 32;
+ }
+ RUN_P1;
+}
+
+void
+sh4_emode_dcache_wbinv_all(void)
+{
+ vaddr_t va = 0;
+ vaddr_t eva = SH4_EMODE_DCACHE_SIZE;
+
+ RUN_P2;
+ while (va < eva) {
+ cache_sh4_emode_op_8lines_32(va, SH4_CCDA, CCDA_ENTRY_MASK,
+ (CCDA_U | CCDA_V), 14);
+ va += 32 * 8;
+ }
+ RUN_P1;
+}
+
+void
+sh4_emode_dcache_wbinv_range_index(vaddr_t va, vsize_t sz)
+{
+ vaddr_t eva = round_line(va + sz);
+ va = trunc_line(va);
+
+ RUN_P2;
+ while ((eva - va) >= (8 * 32)) {
+ cache_sh4_emode_op_8lines_32(va, SH4_CCDA, CCDA_ENTRY_MASK,
+ (CCDA_U | CCDA_V), 14);
+ va += 32 * 8;
+ }
+
+ while (va < eva) {
+ cache_sh4_emode_op_line_32(va, SH4_CCDA, CCDA_ENTRY_MASK,
+ (CCDA_U | CCDA_V), 14);
+ va += 32;
+ }
+ RUN_P1;
+}
diff --git a/sys/arch/sh/sh/clock.c b/sys/arch/sh/sh/clock.c
new file mode 100644
index 00000000000..5db3106de69
--- /dev/null
+++ b/sys/arch/sh/sh/clock.c
@@ -0,0 +1,478 @@
+/* $NetBSD: clock.c,v 1.32 2006/09/05 11:09:36 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+
+#include <dev/clock_subr.h>
+
+#include <sh/clock.h>
+#include <sh/trap.h>
+#include <sh/rtcreg.h>
+#include <sh/tmureg.h>
+
+#include <machine/intr.h>
+
+#define NWDOG 0
+
+#ifndef HZ
+#define HZ 64
+#endif
+#define MINYEAR 2002 /* "today" */
+#define SH_RTC_CLOCK 16384 /* Hz */
+
+/*
+ * OpenBSD/sh clock module
+ * + default 64Hz
+ * + use TMU channel 0 as clock interrupt source.
+ * + use TMU channel 1 and 2 as emulated software interrupt soruce.
+ * + If RTC module is active, TMU channel 0 input source is RTC output.
+ * (1.6384kHz)
+ */
+struct {
+ /* Hard clock */
+ uint32_t hz_cnt; /* clock interrupt interval count */
+ uint32_t cpucycle_1us; /* calibrated loop variable (1 us) */
+ uint32_t tmuclk; /* source clock of TMU0 (Hz) */
+
+ /* RTC ops holder. default SH RTC module */
+ struct rtc_ops rtc;
+ int rtc_initialized;
+
+ uint32_t pclock; /* PCLOCK */
+ uint32_t cpuclock; /* CPU clock */
+ int flags;
+} sh_clock = {
+#ifdef PCLOCK
+ .pclock = PCLOCK,
+#endif
+ .rtc = {
+ /* SH RTC module to default RTC */
+ .init = sh_rtc_init,
+ .get = sh_rtc_get,
+ .set = sh_rtc_set
+ }
+};
+
+uint32_t maxwdog;
+
+/* TMU */
+/* interrupt handler is timing critical. prepared for each. */
+int sh3_clock_intr(void *);
+int sh4_clock_intr(void *);
+
+/*
+ * Estimate CPU and Peripheral clock.
+ */
+#define TMU_START(x) \
+do { \
+ _reg_bclr_1(SH_(TSTR), TSTR_STR##x); \
+ _reg_write_4(SH_(TCNT ## x), 0xffffffff); \
+ _reg_bset_1(SH_(TSTR), TSTR_STR##x); \
+} while (/*CONSTCOND*/0)
+#define TMU_ELAPSED(x) \
+ (0xffffffff - _reg_read_4(SH_(TCNT ## x)))
+void
+sh_clock_init(int flags, struct rtc_ops *rtc)
+{
+ uint32_t s, t0, t1 __attribute__((__unused__));
+
+ sh_clock.flags = flags;
+ if (rtc != NULL)
+ sh_clock.rtc = *rtc; /* structure copy */
+
+ /* Initialize TMU */
+ _reg_write_2(SH_(TCR0), 0);
+ _reg_write_2(SH_(TCR1), 0);
+ _reg_write_2(SH_(TCR2), 0);
+
+ /* Reset RTC alarm and interrupt */
+ _reg_write_1(SH_(RCR1), 0);
+
+ /* Stop all counter */
+ _reg_write_1(SH_(TSTR), 0);
+
+ /*
+ * Estimate CPU clock.
+ */
+ if (sh_clock.flags & SH_CLOCK_NORTC) {
+ /* Set TMU channel 0 source to PCLOCK / 16 */
+ _reg_write_2(SH_(TCR0), TCR_TPSC_P16);
+ sh_clock.tmuclk = sh_clock.pclock / 16;
+ } else {
+ /* Set TMU channel 0 source to RTC counter clock (16.384kHz) */
+ _reg_write_2(SH_(TCR0),
+ CPU_IS_SH3 ? SH3_TCR_TPSC_RTC : SH4_TCR_TPSC_RTC);
+ sh_clock.tmuclk = SH_RTC_CLOCK;
+ }
+
+ s = _cpu_exception_suspend();
+ _cpu_spin(1); /* load function on cache. */
+ TMU_START(0);
+ _cpu_spin(10000000);
+ t0 = TMU_ELAPSED(0);
+ _cpu_exception_resume(s);
+
+ sh_clock.cpuclock = ((10000000 * 10) / t0) * sh_clock.tmuclk;
+ sh_clock.cpucycle_1us = (sh_clock.tmuclk * 10) / t0;
+
+ if (CPU_IS_SH4)
+ sh_clock.cpuclock >>= 1; /* two-issue */
+
+ /*
+ * Estimate PCLOCK
+ */
+ if (sh_clock.pclock == 0) {
+ /* set TMU channel 1 source to PCLOCK / 4 */
+ _reg_write_2(SH_(TCR1), TCR_TPSC_P4);
+ s = _cpu_exception_suspend();
+ _cpu_spin(1); /* load function on cache. */
+ TMU_START(0);
+ TMU_START(1);
+ _cpu_spin(sh_clock.cpucycle_1us * 1000000); /* 1 sec. */
+ t0 = TMU_ELAPSED(0);
+ t1 = TMU_ELAPSED(1);
+ _cpu_exception_resume(s);
+
+ sh_clock.pclock = ((t1 * 4)/ t0) * SH_RTC_CLOCK;
+ }
+
+ /* Stop all counter */
+ _reg_write_1(SH_(TSTR), 0);
+
+#undef TMU_START
+#undef TMU_ELAPSED
+}
+
+int
+sh_clock_get_cpuclock()
+{
+ return (sh_clock.cpuclock);
+}
+
+int
+sh_clock_get_pclock()
+{
+ return (sh_clock.pclock);
+}
+
+void
+setstatclockrate(int newhz)
+{
+ /* XXX not yet */
+}
+
+/*
+ * Return the best possible estimate of the time in the timeval to
+ * which tv points.
+ */
+void
+microtime(struct timeval *tv)
+{
+ static struct timeval lasttime;
+ int s;
+
+ s = splclock();
+ *tv = time;
+ splx(s);
+
+ tv->tv_usec += ((sh_clock.hz_cnt - _reg_read_4(SH_(TCNT0)))
+ * 1000000) / sh_clock.tmuclk;
+ while (tv->tv_usec >= 1000000) {
+ tv->tv_usec -= 1000000;
+ tv->tv_sec++;
+ }
+
+ if (tv->tv_sec == lasttime.tv_sec &&
+ tv->tv_usec <= lasttime.tv_usec &&
+ (tv->tv_usec = lasttime.tv_usec + 1) >= 1000000) {
+ tv->tv_usec -= 1000000;
+ tv->tv_sec++;
+ }
+ lasttime = *tv;
+}
+
+/*
+ * Wait at least `n' usec.
+ */
+void
+delay(int n)
+{
+ _cpu_spin(sh_clock.cpucycle_1us * n);
+}
+
+/*
+ * Start the clock interrupt.
+ */
+void
+cpu_initclocks()
+{
+ if (sh_clock.pclock == 0)
+ panic("No PCLOCK information.");
+
+ /* Set global variables. */
+ hz = HZ;
+ tick = 1000000 / hz;
+
+ /*
+ * Use TMU channel 0 as hard clock
+ */
+ _reg_bclr_1(SH_(TSTR), TSTR_STR0);
+
+ if (sh_clock.flags & SH_CLOCK_NORTC) {
+ /* use PCLOCK/16 as TMU0 source */
+ _reg_write_2(SH_(TCR0), TCR_UNIE | TCR_TPSC_P16);
+ } else {
+ /* use RTC clock as TMU0 source */
+ _reg_write_2(SH_(TCR0), TCR_UNIE |
+ (CPU_IS_SH3 ? SH3_TCR_TPSC_RTC : SH4_TCR_TPSC_RTC));
+ }
+ sh_clock.hz_cnt = sh_clock.tmuclk / hz - 1;
+
+ _reg_write_4(SH_(TCOR0), sh_clock.hz_cnt);
+ _reg_write_4(SH_(TCNT0), sh_clock.hz_cnt);
+
+ intc_intr_establish(SH_INTEVT_TMU0_TUNI0, IST_LEVEL, IPL_CLOCK,
+ CPU_IS_SH3 ? sh3_clock_intr : sh4_clock_intr, NULL, "clock");
+ /* start hardclock */
+ _reg_bset_1(SH_(TSTR), TSTR_STR0);
+
+ /*
+ * TMU channel 1, 2 are one shot timer.
+ */
+ _reg_write_2(SH_(TCR1), TCR_UNIE | TCR_TPSC_P4);
+ _reg_write_4(SH_(TCOR1), 0xffffffff);
+ _reg_write_2(SH_(TCR2), TCR_UNIE | TCR_TPSC_P4);
+ _reg_write_4(SH_(TCOR2), 0xffffffff);
+
+ /* Make sure to start RTC */
+ sh_clock.rtc.init(sh_clock.rtc._cookie);
+}
+
+void
+inittodr(time_t base)
+{
+ struct clock_ymdhms dt;
+ time_t rtc;
+ int s;
+
+ if (!sh_clock.rtc_initialized)
+ sh_clock.rtc_initialized = 1;
+
+ sh_clock.rtc.get(sh_clock.rtc._cookie, base, &dt);
+ rtc = clock_ymdhms_to_secs(&dt);
+
+#ifdef DEBUG
+ printf("inittodr: %d/%d/%d/%d/%d/%d(%d)\n", dt.dt_year,
+ dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec,
+ dt.dt_wday);
+#endif
+
+ if (!(sh_clock.flags & SH_CLOCK_NOINITTODR) &&
+ (rtc < base ||
+ dt.dt_year < MINYEAR || dt.dt_year > 2037 ||
+ dt.dt_mon < 1 || dt.dt_mon > 12 ||
+ dt.dt_wday > 6 ||
+ dt.dt_day < 1 || dt.dt_day > 31 ||
+ dt.dt_hour > 23 || dt.dt_min > 59 || dt.dt_sec > 59)) {
+ /*
+ * Believe the time in the file system for lack of
+ * anything better, resetting the RTC.
+ */
+ s = splclock();
+ time.tv_sec = base;
+ time.tv_usec = 0;
+ splx(s);
+ printf("WARNING: preposterous clock chip time\n");
+ resettodr();
+ printf(" -- CHECK AND RESET THE DATE!\n");
+ return;
+ }
+
+ s = splclock();
+ time.tv_sec = rtc;
+ time.tv_usec = 0;
+ splx(s);
+
+ return;
+}
+
+void
+resettodr()
+{
+ struct clock_ymdhms dt;
+ int s;
+
+ if (!sh_clock.rtc_initialized)
+ return;
+
+ s = splclock();
+ clock_secs_to_ymdhms(time.tv_sec, &dt);
+ splx(s);
+
+ sh_clock.rtc.set(sh_clock.rtc._cookie, &dt);
+#ifdef DEBUG
+ printf("%s: %d/%d/%d/%d/%d/%d(%d) rtc_offset %d\n", __FUNCTION__,
+ dt.dt_year, dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec,
+ dt.dt_wday, rtc_offset);
+#endif
+}
+
+#ifdef SH3
+int
+sh3_clock_intr(void *arg) /* trap frame */
+{
+#if (NWDOG > 0)
+ uint32_t i;
+
+ i = (uint32_t)SHREG_WTCNT_R;
+ if (i > maxwdog)
+ maxwdog = i;
+ wdog_wr_cnt(0); /* reset to zero */
+#endif
+ /* clear underflow status */
+ _reg_bclr_2(SH3_TCR0, TCR_UNF);
+
+ hardclock(arg);
+
+ return (1);
+}
+#endif /* SH3 */
+
+#ifdef SH4
+int
+sh4_clock_intr(void *arg) /* trap frame */
+{
+#if (NWDOG > 0)
+ uint32_t i;
+
+ i = (uint32_t)SHREG_WTCNT_R;
+ if (i > maxwdog)
+ maxwdog = i;
+ wdog_wr_cnt(0); /* reset to zero */
+#endif
+ /* clear underflow status */
+ _reg_bclr_2(SH4_TCR0, TCR_UNF);
+
+ hardclock(arg);
+
+ return (1);
+}
+#endif /* SH4 */
+
+/*
+ * SH3 RTC module ops.
+ */
+
+void
+sh_rtc_init(void *cookie)
+{
+ /* Make sure to start RTC */
+ _reg_write_1(SH_(RCR2), SH_RCR2_ENABLE | SH_RCR2_START);
+}
+
+void
+sh_rtc_get(void *cookie, time_t base, struct clock_ymdhms *dt)
+{
+ int retry = 8;
+
+ /* disable carry interrupt */
+ _reg_bclr_1(SH_(RCR1), SH_RCR1_CIE);
+
+ do {
+ uint8_t r = _reg_read_1(SH_(RCR1));
+ r &= ~SH_RCR1_CF;
+ r |= SH_RCR1_AF; /* don't clear alarm flag */
+ _reg_write_1(SH_(RCR1), r);
+
+ if (CPU_IS_SH3)
+ dt->dt_year = FROMBCD(_reg_read_1(SH3_RYRCNT));
+ else
+ dt->dt_year = FROMBCD(_reg_read_2(SH4_RYRCNT) & 0x00ff);
+
+ /* read counter */
+#define RTCGET(x, y) dt->dt_ ## x = FROMBCD(_reg_read_1(SH_(R ## y ## CNT)))
+ RTCGET(mon, MON);
+ RTCGET(wday, WK);
+ RTCGET(day, DAY);
+ RTCGET(hour, HR);
+ RTCGET(min, MIN);
+ RTCGET(sec, SEC);
+#undef RTCGET
+ } while ((_reg_read_1(SH_(RCR1)) & SH_RCR1_CF) && --retry > 0);
+
+ if (retry == 0) {
+ printf("rtc_gettime: couldn't read RTC register.\n");
+ memset(dt, 0, sizeof(*dt));
+ return;
+ }
+
+ dt->dt_year = (dt->dt_year % 100) + 1900;
+ if (dt->dt_year < 1970)
+ dt->dt_year += 100;
+}
+
+void
+sh_rtc_set(void *cookie, struct clock_ymdhms *dt)
+{
+ uint8_t r;
+
+ /* stop clock */
+ r = _reg_read_1(SH_(RCR2));
+ r |= SH_RCR2_RESET;
+ r &= ~SH_RCR2_START;
+ _reg_write_1(SH_(RCR2), r);
+
+ /* set time */
+ if (CPU_IS_SH3)
+ _reg_write_1(SH3_RYRCNT, TOBCD(dt->dt_year % 100));
+ else
+ _reg_write_2(SH4_RYRCNT, TOBCD(dt->dt_year % 100));
+#define RTCSET(x, y) _reg_write_1(SH_(R ## x ## CNT), TOBCD(dt->dt_ ## y))
+ RTCSET(MON, mon);
+ RTCSET(WK, wday);
+ RTCSET(DAY, day);
+ RTCSET(HR, hour);
+ RTCSET(MIN, min);
+ RTCSET(SEC, sec);
+#undef RTCSET
+ /* start clock */
+ _reg_write_1(SH_(RCR2), r | SH_RCR2_START);
+}
diff --git a/sys/arch/sh/sh/cpu.c b/sys/arch/sh/sh/cpu.c
new file mode 100644
index 00000000000..a3c5b98f83f
--- /dev/null
+++ b/sys/arch/sh/sh/cpu.c
@@ -0,0 +1,79 @@
+/* $OpenBSD: cpu.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: cpu.c,v 1.8 2006/01/02 23:16:20 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <sh/clock.h>
+#include <sh/cache.h>
+#include <sh/mmu.h>
+
+#include <machine/autoconf.h>
+
+int cpu_match(struct device *, void *, void *);
+void cpu_attach(struct device *, struct device *, void *);
+
+struct cfattach cpu_ca = {
+ sizeof(struct device), cpu_match, cpu_attach
+};
+
+struct cfdriver cpu_cd = {
+ 0, "cpu", DV_DULL
+};
+
+int
+cpu_match(struct device *parent, void *vcf, void *aux)
+{
+ struct mainbus_attach_args *ma = aux;
+
+ if (strcmp(ma->ma_name, cpu_cd.cd_name) != 0)
+ return (0);
+
+ return (1);
+}
+
+void
+cpu_attach(struct device *parent, struct device *self, void *aux)
+{
+#define MHZ(x) ((x) / 1000000), (((x) % 1000000) / 1000)
+ printf(": HITACHI SH%d %d.%02d MHz PCLOCK %d.%02d MHz\n",
+ CPU_IS_SH3 ? 3 : 4, MHZ(sh_clock_get_cpuclock()),
+ MHZ(sh_clock_get_pclock()));
+#undef MHZ
+ sh_cache_information();
+ sh_mmu_information();
+}
diff --git a/sys/arch/sh/sh/db_disasm.c b/sys/arch/sh/sh/db_disasm.c
new file mode 100644
index 00000000000..a309151d677
--- /dev/null
+++ b/sys/arch/sh/sh/db_disasm.c
@@ -0,0 +1,1671 @@
+/* $OpenBSD: db_disasm.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: db_disasm.c,v 1.13 2006/01/21 02:09:06 uwe Exp $ */
+
+/*
+ * Copyright (c) 1998-2000 Internet Initiative Japan Inc.
+ * All rights reserved.
+ *
+ * Author: Akinori Koketsu
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistribution with functional modification must include
+ * prominent notice stating how and when and by whom it is
+ * modified.
+ * 3. Redistributions in binary form have to be along with the source
+ * code or documentation which include above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 4. All commercial advertising materials mentioning features or use
+ * of this software must display the following acknowledgement:
+ * This product includes software developed by Internet
+ * Initiative Japan Inc.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/db_machdep.h>
+
+#include <ddb/db_interface.h>
+#include <ddb/db_output.h>
+
+static void get_opcode(uint16_t *, char *, size_t);
+static void get_ascii(unsigned char *, char *);
+static void f_02(uint16_t *, char *, size_t);
+static void f_03(uint16_t *, char *, size_t);
+static void f_04(uint16_t *, char *, size_t);
+static void f_08(uint16_t *, char *, size_t);
+static void f_09(uint16_t *, char *, size_t);
+static void f_0a(uint16_t *, char *, size_t);
+static void f_0b(uint16_t *, char *, size_t);
+static void f_0c(uint16_t *, char *, size_t);
+static void f_10(uint16_t *, char *, size_t);
+static void f_20(uint16_t *, char *, size_t);
+static void f_24(uint16_t *, char *, size_t);
+static void f_28(uint16_t *, char *, size_t);
+static void f_2c(uint16_t *, char *, size_t);
+static void f_30(uint16_t *, char *, size_t);
+static void f_34(uint16_t *, char *, size_t);
+static void f_38(uint16_t *, char *, size_t);
+static void f_3c(uint16_t *, char *, size_t);
+static void f_40(uint16_t *, char *, size_t);
+static void f_41(uint16_t *, char *, size_t);
+static void f_42(uint16_t *, char *, size_t);
+static void f_43(uint16_t *, char *, size_t);
+static void f_44(uint16_t *, char *, size_t);
+static void f_45(uint16_t *, char *, size_t);
+static void f_46(uint16_t *, char *, size_t);
+static void f_47(uint16_t *, char *, size_t);
+static void f_48(uint16_t *, char *, size_t);
+static void f_49(uint16_t *, char *, size_t);
+static void f_4a(uint16_t *, char *, size_t);
+static void f_4b(uint16_t *, char *, size_t);
+static void f_4c(uint16_t *, char *, size_t);
+static void f_4d(uint16_t *, char *, size_t);
+static void f_4e(uint16_t *, char *, size_t);
+static void f_4f(uint16_t *, char *, size_t);
+static void f_50(uint16_t *, char *, size_t);
+static void f_60(uint16_t *, char *, size_t);
+static void f_64(uint16_t *, char *, size_t);
+static void f_68(uint16_t *, char *, size_t);
+static void f_6c(uint16_t *, char *, size_t);
+static void f_70(uint16_t *, char *, size_t);
+static void f_80(uint16_t *, char *, size_t);
+static void f_90(uint16_t *, char *, size_t);
+static void f_a0(uint16_t *, char *, size_t);
+static void f_b0(uint16_t *, char *, size_t);
+static void f_c0(uint16_t *, char *, size_t);
+static void f_d0(uint16_t *, char *, size_t);
+static void f_e0(uint16_t *, char *, size_t);
+static void f_f0(uint16_t *, char *, size_t);
+static void f_f4(uint16_t *, char *, size_t);
+static void f_f8(uint16_t *, char *, size_t);
+static void f_fc(uint16_t *, char *, size_t);
+static void f_fd(uint16_t *, char *, size_t);
+static void f_fe(uint16_t *, char *, size_t);
+
+typedef void (*rasm_t)(uint16_t *, char *, size_t);
+static rasm_t f[16][16] = {
+ { /* [0][0-7] */ NULL, NULL, f_02, f_03, f_04, f_04, f_04, f_04,
+ /* [0][8-f] */ f_08, f_09, f_0a, f_0b, f_0c, f_0c, f_0c, f_0c },
+ { /* [1][0-7] */ f_10, f_10, f_10, f_10, f_10, f_10, f_10, f_10,
+ /* [1][8-f] */ f_10, f_10, f_10, f_10, f_10, f_10, f_10, f_10 },
+ { /* [2][0-7] */ f_20, f_20, f_20, f_20, f_24, f_24, f_24, f_24,
+ /* [2][8-f] */ f_28, f_28, f_28, f_28, f_2c, f_2c, f_2c, f_2c },
+ { /* [3][0-7] */ f_30, f_30, f_30, f_30, f_34, f_34, f_34, f_34,
+ /* [3][8-f] */ f_38, f_38, f_38, f_38, f_3c, f_3c, f_3c, f_3c },
+ { /* [4][0-7] */ f_40, f_41, f_42, f_43, f_44, f_45, f_46, f_47,
+ /* [4][8-f] */ f_48, f_49, f_4a, f_4b, f_4c, f_4d, f_4e, f_4f },
+ { /* [5][0-7] */ f_50, f_50, f_50, f_50, f_50, f_50, f_50, f_50,
+ /* [5][8-f] */ f_50, f_50, f_50, f_50, f_50, f_50, f_50, f_50 },
+ { /* [6][0-7] */ f_60, f_60, f_60, f_60, f_64, f_64, f_64, f_64,
+ /* [6][8-f] */ f_68, f_68, f_68, f_68, f_6c, f_6c, f_6c, f_6c },
+ { /* [7][0-7] */ f_70, f_70, f_70, f_70, f_70, f_70, f_70, f_70,
+ /* [7][8-f] */ f_70, f_70, f_70, f_70, f_70, f_70, f_70, f_70 },
+ { /* [8][0-7] */ f_80, f_80, f_80, f_80, f_80, f_80, f_80, f_80,
+ /* [8][8-f] */ f_80, f_80, f_80, f_80, f_80, f_80, f_80, f_80 },
+ { /* [9][0-7] */ f_90, f_90, f_90, f_90, f_90, f_90, f_90, f_90,
+ /* [9][8-f] */ f_90, f_90, f_90, f_90, f_90, f_90, f_90, f_90 },
+ { /* [a][0-7] */ f_a0, f_a0, f_a0, f_a0, f_a0, f_a0, f_a0, f_a0,
+ /* [a][8-f] */ f_a0, f_a0, f_a0, f_a0, f_a0, f_a0, f_a0, f_a0 },
+ { /* [b][0-7] */ f_b0, f_b0, f_b0, f_b0, f_b0, f_b0, f_b0, f_b0,
+ /* [b][8-f] */ f_b0, f_b0, f_b0, f_b0, f_b0, f_b0, f_b0, f_b0 },
+ { /* [c][0-7] */ f_c0, f_c0, f_c0, f_c0, f_c0, f_c0, f_c0, f_c0,
+ /* [c][8-f] */ f_c0, f_c0, f_c0, f_c0, f_c0, f_c0, f_c0, f_c0 },
+ { /* [d][0-7] */ f_d0, f_d0, f_d0, f_d0, f_d0, f_d0, f_d0, f_d0,
+ /* [d][8-f] */ f_d0, f_d0, f_d0, f_d0, f_d0, f_d0, f_d0, f_d0 },
+ { /* [e][0-7] */ f_e0, f_e0, f_e0, f_e0, f_e0, f_e0, f_e0, f_e0,
+ /* [e][8-f] */ f_e0, f_e0, f_e0, f_e0, f_e0, f_e0, f_e0, f_e0 },
+ { /* [f][0-7] */ f_f0, f_f0, f_f0, f_f0, f_f4, f_f4, f_f4, f_f4,
+ /* [f][8-f] */ f_f8, f_f8, f_f8, f_f8, f_fc, f_fd, f_fe, NULL }
+};
+
+db_addr_t
+db_disasm(db_addr_t loc, boolean_t altfmt)
+{
+ char line[40], ascii[4];
+ void *pc = (void *)loc;
+
+ get_opcode(pc, line, sizeof line);
+ if (altfmt) {
+ get_ascii(pc, ascii);
+ db_printf("%-32s ! %s\n", line, ascii);
+ } else
+ db_printf("%s\n", line);
+
+ return (loc + 2);
+}
+
+static void
+get_ascii(unsigned char *cp, char *str)
+{
+
+ *str++ = (0x20 <= *cp && *cp < 0x7f) ? *cp : '.';
+ cp++;
+ *str++ = (0x20 <= *cp && *cp < 0x7f) ? *cp : '.';
+ *str = '\0';
+}
+
+static void
+get_opcode(uint16_t *sp, char *buf, size_t bufsiz)
+{
+ int n0, n3;
+
+ strlcpy(buf, "unknown opcode", bufsiz);
+
+ n0 = (*sp & 0xf000) >> 12;
+ n3 = (*sp & 0x000f);
+
+ if (f[n0][n3] != NULL) {
+ (*f[n0][n3])(sp, buf, bufsiz);
+ }
+}
+
+static void
+f_02(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, type, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ type = (*code & 0x00c0) >> 6;
+ md = (*code & 0x0030) >> 4;
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "stc sr, r%d", rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "stc gbr, r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "stc vbr, r%d", rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "stc ssr, r%d", rn);
+ break;
+
+ }
+ break;
+
+ case 1:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "stc spc, r%d", rn);
+ break;
+ }
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "stc r%d_bank, r%d", md, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "stc r%d_bank, r%d", md+4, rn);
+ break;
+ } /* end of switch (type) */
+}
+
+static void
+f_03(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, type, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ type = (*code & 0x00c0) >> 6;
+ md = (*code & 0x0030) >> 4;
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "bsrf r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "braf r%d", rn);
+ break;
+ }
+ break;
+
+ case 2:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "pref @r%d", rn);
+ break;
+ }
+ break;
+ } /* end of switch (type) */
+}
+
+
+static void
+f_04(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "mov.b r%d, @(r0, r%d)", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "mov.w r%d, @(r0, r%d)", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "mov.l r%d, @(r0, r%d)", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "mul.l r%d, r%d)", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_08(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int n1, type, md;
+
+ n1 = (*code & 0x0f00) >> 8;
+ type = (*code & 0x00c0) >> 6;
+ md = (*code & 0x0030) >> 4;
+
+ if (n1 != 0)
+ return;
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ strlcpy(buf, "clrt", bufsiz);
+ break;
+
+ case 1:
+ strlcpy(buf, "sett", bufsiz);
+ break;
+
+ case 2:
+ strlcpy(buf, "clrmac", bufsiz);
+ break;
+
+ case 3:
+ strlcpy(buf, "ldtlb", bufsiz);
+ break;
+ }
+ break;
+
+ case 1:
+ switch (md) {
+ case 0:
+ strlcpy(buf, "clrs", bufsiz);
+ break;
+
+ case 1:
+ strlcpy(buf, "sets", bufsiz);
+ break;
+ }
+ break;
+ } /* end of switch (type) */
+}
+
+static void
+f_09(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, fx;
+
+ rn = (*code & 0x0f00) >> 8;
+ fx = (*code & 0x00f0) >> 4;
+
+ switch (fx) {
+ case 0:
+ if (rn != 0)
+ return;
+ strlcpy(buf, "nop", bufsiz);
+ break;
+
+ case 1:
+ if (rn != 0)
+ return;
+ strlcpy(buf, "div0u", bufsiz);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "movt r%d", rn);
+ break;
+ } /* end of switch (fx) */
+}
+
+static void
+f_0a(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, type, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ type = (*code & 0x00c0) >> 6;
+ md = (*code & 0x0030) >> 4;
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "sts mach, r%d", rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "sts macl, r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "sts pr, r%d", rn);
+ break;
+ }
+ break;
+
+ case 1:
+ switch (md) {
+ case 1:
+ snprintf(buf, bufsiz, "sts fpul, r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "sts fpscr, r%d", rn);
+ break;
+ }
+ break;
+ } /* end of switch (type) */
+}
+
+static void
+f_0b(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int n1, fx;
+
+ n1 = (*code & 0x0f00) >> 8;
+ if (n1 != 0)
+ return;
+
+ fx = (*code & 0x00f0) >> 4;
+ switch (fx) {
+ case 0:
+ strlcpy(buf, "rts", bufsiz);
+ break;
+
+ case 1:
+ strlcpy(buf, "sleep", bufsiz);
+ break;
+
+ case 2:
+ strlcpy(buf, "rte", bufsiz);
+ break;
+ } /* end of switch (fx) */
+}
+
+static void
+f_0c(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "mov.b @(r0, r%d), r%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "mov.w @(r0, r%d), r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "mov.l @(r0, r%d), r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "mac.l @r%d+, r%d+", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_10(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, disp;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ disp = (*code & 0x000f);
+ disp *= 4;
+
+ snprintf(buf, bufsiz, "mov.l r%d, @(%d, r%d)", rm, disp, rn);
+}
+
+static void
+f_20(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "mov.b r%d, @r%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "mov.w r%d, @r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "mov.l r%d, @r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+
+static void
+f_24(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "mov.b r%d, @-r%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "mov.w r%d, @-r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "mov.l r%d, @-r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "div0s r%d, r%d)", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_28(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "tst r%d, r%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "and r%d, r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "xor r%d, r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "or r%d, r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+
+static void
+f_2c(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "cmp/str r%d, r%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "xtrct r%d, r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "mulu.w r%d, r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "muls.w r%d, r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_30(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "cmp/eq r%d, r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "cmp/hs r%d, r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "cmp/ge r%d, r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+
+static void
+f_34(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "div1 r%d, r%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "dmulu.l r%d, r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "cmp/hi r%d, r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "cmp/gt r%d, r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_38(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "sub r%d, r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "subc r%d, r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "subv r%d, r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+
+static void
+f_3c(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "add r%d, r%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "dmulu.l r%d, r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "addc r%d, r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "addv r%d, r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+
+static void
+f_40(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, fx;
+
+ rn = (*code & 0x0f00) >> 8;
+ fx = (*code & 0x00f0) >> 4;
+
+ switch (fx) {
+ case 0:
+ snprintf(buf, bufsiz, "shll r%d", rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "dt r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "shal r%d", rn);
+ break;
+ } /* end of switch (fx) */
+}
+
+static void
+f_41(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, fx;
+
+ rn = (*code & 0x0f00) >> 8;
+ fx = (*code & 0x00f0) >> 4;
+
+ switch (fx) {
+ case 0:
+ snprintf(buf, bufsiz, "shlr r%d", rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "cmp/pz r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "shar r%d", rn);
+ break;
+ } /* end of switch (fx) */
+}
+
+
+static void
+f_42(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, type, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ type = (*code & 0x00c0) >> 6;
+ md = (*code & 0x0030) >> 4;
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "sts.l mach, @-r%d", rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "sts.l macl, @-r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "sts.l pr, @-r%d", rn);
+ break;
+ }
+ break;
+
+ case 1:
+ switch (md) {
+ case 1:
+ snprintf(buf, bufsiz, "sts.l fpul, @-r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "sts.l fpscr, @-r%d", rn);
+ break;
+ }
+ break;
+ } /* end of switch (type) */
+}
+
+static void
+f_43(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, type, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ type = (*code & 0x00c0) >> 6;
+ md = (*code & 0x0030) >> 4;
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "stc.l sr, @-r%d", rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "stc.l gbr, @-r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "stc.l vbr, @-r%d", rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "stc.l ssr, @-r%d", rn);
+ break;
+ }
+ break;
+
+ case 1:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "stc.l spc, @-r%d", rn);
+ break;
+ }
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "stc.l r%d_bank, @-r%d", md, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "stc.l r%d_bank, @-r%d", md+4, rn);
+ break;
+ } /* end of switch (type) */
+}
+
+static void
+f_44(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, fx;
+
+ rn = (*code & 0x0f00) >> 8;
+ fx = (*code & 0x00f0) >> 4;
+
+ switch (fx) {
+ case 0:
+ snprintf(buf, bufsiz, "rotl r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "rotcl r%d", rn);
+ break;
+ } /* end of switch (fx) */
+}
+
+static void
+f_45(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, fx;
+
+ rn = (*code & 0x0f00) >> 8;
+ fx = (*code & 0x00f0) >> 4;
+
+ switch (fx) {
+ case 0:
+ snprintf(buf, bufsiz, "rotr r%d", rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "cmp/pl r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "rotcr r%d", rn);
+ break;
+ } /* end of switch (fx) */
+}
+
+static void
+f_46(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rm, type, md;
+
+ rm = (*code & 0x0f00) >> 8;
+ type = (*code & 0x00c0) >> 6;
+ md = (*code & 0x0030) >> 4;
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "lds.l @r%d+, mach", rm);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "lds.l @r%d+, macl", rm);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "lds.l @r%d+, pr", rm);
+ break;
+ }
+ break;
+
+ case 1:
+ switch (md) {
+ case 1:
+ snprintf(buf, bufsiz, "lds.l @r%d+, fpul", rm);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "lds.l @r%d+, fpscr", rm);
+ break;
+ }
+ break;
+ } /* end of switch (type) */
+}
+
+static void
+f_47(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rm, type, md;
+
+ rm = (*code & 0x0f00) >> 8;
+ type = (*code & 0x00c0) >> 6;
+ md = (*code & 0x0030) >> 4;
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "ldc.l @r%d+, sr", rm);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "ldc.l @r%d+, gbr", rm);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "ldc.l @r%d+, vbr", rm);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "ldc.l @r%d+, ssr", rm);
+ break;
+ }
+ break;
+
+ case 1:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "ldc.l @r%d+, spc", rm);
+ break;
+ }
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "ldc.l @r%d+, r%d_bank", rm, md);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "ldc.l @r%d+, r%d_bank", rm, md+4);
+ break;
+ } /* end of switch (type) */
+}
+
+static void
+f_48(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, fx;
+
+ rn = (*code & 0x0f00) >> 8;
+ fx = (*code & 0x00f0) >> 4;
+
+ switch (fx) {
+ case 0:
+ snprintf(buf, bufsiz, "shll2 r%d", rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "shll8 r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "shll16 r%d", rn);
+ break;
+ } /* end of switch (fx) */
+}
+
+static void
+f_49(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, fx;
+
+ rn = (*code & 0x0f00) >> 8;
+ fx = (*code & 0x00f0) >> 4;
+
+ switch (fx) {
+ case 0:
+ snprintf(buf, bufsiz, "shlr2 r%d", rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "shlr8 r%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "shlr16 r%d", rn);
+ break;
+ } /* end of switch (fx) */
+}
+
+static void
+f_4a(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rm, type, md;
+
+ rm = (*code & 0x0f00) >> 8;
+ type = (*code & 0x00c0) >> 6;
+ md = (*code & 0x0030) >> 4;
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "lds r%d, mach", rm);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "lds r%d, macl", rm);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "lds r%d, pr", rm);
+ break;
+ }
+ break;
+
+ case 1:
+ switch (md) {
+ case 1:
+ snprintf(buf, bufsiz, "lds r%d, fpul", rm);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "lds r%d, fpscr", rm);
+ break;
+ }
+ break;
+ } /* end of switch (type) */
+}
+
+static void
+f_4b(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rm, fx;
+
+ rm = (*code & 0x0f00) >> 8;
+ fx = (*code & 0x00f0) >> 4;
+
+ switch (fx) {
+ case 0:
+ snprintf(buf, bufsiz, "jsr @r%d", rm);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "tas.b @r%d", rm);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "jmp @r%d", rm);
+ break;
+ } /* end of switch (fx) */
+}
+
+static void
+f_4c(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ snprintf(buf, bufsiz, "shad r%d, r%d", rm, rn);
+}
+
+static void
+f_4d(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ snprintf(buf, bufsiz, "shld r%d, r%d", rm, rn);
+}
+
+static void
+f_4e(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rm, type, md;
+
+ rm = (*code & 0x0f00) >> 8;
+ type = (*code & 0x00c0) >> 6;
+ md = (*code & 0x0030) >> 4;
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "ldc r%d, sr", rm);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "ldc r%d, gbr", rm);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "ldc r%d, vbr", rm);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "ldc r%d, ssr", rm);
+ break;
+ }
+ break;
+
+ case 1:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "ldc r%d, spc", rm);
+ break;
+ }
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "ldc r%d, r%d_bank", rm, md);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "ldc r%d, r%d_bank", rm, md+4);
+ break;
+ } /* end of switch (type) */
+}
+
+static void
+f_4f(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ snprintf(buf, bufsiz, "mac.w @r%d+, @r%d+", rm, rn);
+}
+
+static void
+f_50(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, disp;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ disp = (*code & 0x000f);
+ disp *= 4;
+
+ snprintf(buf, bufsiz, "mov.l @(%d, r%d), r%d", disp, rm, rn);
+}
+
+static void
+f_60(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "mov.b @r%d, r%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "mov.w @r%d, r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "mov.l @r%d, r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "mov r%d, r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_64(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "mov.b @r%d+, r%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "mov.w @r%d+, r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "mov.l @r%d+, r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "not r%d, r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_68(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "swap.b r%d, r%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "swap.w r%d, r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "negc r%d, r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "neg r%d, r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_6c(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "extu.b r%d, r%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "extu.w r%d, r%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "exts.b r%d, r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "exts.w r%d, r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_70(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, imm;
+
+ rn = (*code & 0x0f00) >> 8;
+ imm = (int) ((char) (*code & 0x00ff));
+
+ snprintf(buf, bufsiz, "add #0x%x, r%d", imm, rn);
+}
+
+static void
+f_80(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int type, md, rn, disp;
+
+ type = (*code & 0x0c00) >> 10;
+ md = (*code & 0x0300) >> 8;
+
+ switch (type) {
+ case 0:
+ rn = (*code & 0x00f0) >> 4;
+ disp = (*code & 0x000f);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "mov.b r0, @(%d, r%d)",
+ disp, rn);
+ break;
+
+ case 1:
+ disp *= 2;
+ snprintf(buf, bufsiz, "mov.w r0, @(%d, r%d)",
+ disp, rn);
+ break;
+ }
+ break;
+
+ case 1:
+ rn = (*code & 0x00f0) >> 4;
+ disp = (*code & 0x000f);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "mov.b @(%d, r%d), r0",
+ disp, rn);
+ break;
+
+ case 1:
+ disp *= 2;
+ snprintf(buf, bufsiz, "mov.w @(%d, r%d), r0",
+ disp, rn);
+ break;
+ }
+ break;
+
+ case 2:
+ disp = (*code & 0x00ff);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "cmp/eq #%d, r0", disp);
+ break;
+
+ case 1:
+ disp = (int) ((char) disp);
+ disp *= 2;
+ snprintf(buf, bufsiz, "bt 0x%x", disp);
+ break;
+
+ case 3:
+ disp = (int) ((char) disp);
+ disp *= 2;
+ snprintf(buf, bufsiz, "bf 0x%x", disp);
+ break;
+ }
+ break;
+
+ case 3:
+ disp = (int) ((char) (*code & 0x00ff));
+ disp *= 2;
+
+ switch (md) {
+ case 1:
+ snprintf(buf, bufsiz, "bt/s 0x%x", disp);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "bf/s 0x%x", disp);
+ break;
+ }
+ break;
+ } /* end of switch (type) */
+}
+
+static void
+f_90(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, disp;
+
+ rn = (*code & 0x0f00) >> 8;
+ disp = (*code & 0x00ff);
+ disp *= 2;
+
+ snprintf(buf, bufsiz, "mov.w @(%d, pc), r%d", disp, rn);
+}
+
+static void
+f_a0(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int disp;
+
+ disp = (*code & 0x0fff);
+ if (disp & 0x0800) /* negative displacement? */
+ disp |= 0xfffff000; /* sign extend */
+ disp *= 2;
+
+ snprintf(buf, bufsiz, "bra %d(0x%x)", disp, disp);
+}
+
+static void
+f_b0(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int disp;
+
+ disp = (*code & 0x0fff);
+ if (disp & 0x0800) /* negative displacement? */
+ disp |= 0xfffff000; /* sign extend */
+ disp *= 2;
+
+ snprintf(buf, bufsiz, "bsr %d(0x%x)", disp, disp);
+}
+
+static void
+f_c0(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int type, md, imm;
+
+ type = (*code & 0x0c00) >> 10;
+ md = (*code & 0x0300) >> 8;
+ imm = (*code & 0x00ff);
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "mov.b r0, @(%d, gbr)", imm);
+ break;
+
+ case 1:
+ imm *= 2;
+ snprintf(buf, bufsiz, "mov.w r0, @(%d, gbr)", imm);
+ break;
+
+ case 2:
+ imm *= 4;
+ snprintf(buf, bufsiz, "mov.l r0, @(%d, gbr)", imm);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "trapa #%d", imm);
+ break;
+ }
+ break;
+
+ case 1:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "mov.b @(%d, gbr), r0", imm);
+ break;
+
+ case 1:
+ imm *= 2;
+ snprintf(buf, bufsiz, "mov.w @(%d, gbr), r0", imm);
+ break;
+
+ case 2:
+ imm *= 4;
+ snprintf(buf, bufsiz, "mov.l @(%d, gbr), r0", imm);
+ break;
+
+ case 3:
+ imm *= 4;
+ snprintf(buf, bufsiz, "mova @(%d, pc), r0", imm);
+ break;
+ }
+ break;
+
+ case 2:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "tst #%d, r0", imm);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "and #%d, r0", imm);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "xor #%d, r0", imm);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "or #%d, r0", imm);
+ break;
+ }
+ break;
+
+ case 3:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "tst.b #%d, @(r0, gbr)", imm);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "and.b #%d, @(r0, gbr)", imm);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "xor.b #%d, @(r0, gbr)", imm);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "or.b #%d, @(r0, gbr)", imm);
+ break;
+ }
+ break;
+ } /* end of switch (type) */
+}
+
+
+static void
+f_d0(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, disp;
+
+ rn = (*code & 0x0f00) >> 8;
+ disp = (*code & 0x00ff);
+ disp *= 4;
+
+ snprintf(buf, bufsiz, "mov.l @(%d, pc), r%d", disp, rn);
+}
+
+static void
+f_e0(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, imm;
+
+ rn = (*code & 0x0f00) >> 8;
+ imm = (int) ((char) (*code & 0x00ff));
+
+ snprintf(buf, bufsiz, "mov #0x%x, r%d", imm, rn);
+}
+
+static void
+f_f0(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "fadd fr%d, fr%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "fsub fr%d, fr%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "fmul fr%d, fr%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "fdiv fr%d, fr%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_f4(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "fcmp/eq fr%d, fr%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "fcmp/gt fr%d, fr%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "fmov.s @(r0, r%d), fr%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "fmov.s fr%d, @(r0, r%d)", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_f8(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+ md = (*code & 0x0003);
+
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "fmov.s @r%d, fr%d", rm, rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "fmov.s @r%d+, fr%d", rm, rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "fmov.s fr%d, @r%d", rm, rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "fmov.s fr%d, @-r%d", rm, rn);
+ break;
+ } /* end of switch (md) */
+}
+
+static void
+f_fc(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+
+ snprintf(buf, bufsiz, "fmov fr%d, fr%d", rm, rn);
+}
+
+static void
+f_fd(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, type, md;
+
+ rn = (*code & 0x0f00) >> 8;
+ type = (*code & 0x00c0) >> 6;
+ md = (*code & 0x0030) >> 4;
+
+ switch (type) {
+ case 0:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "fsts fpul, fr%d", rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "flds fr%d, fpul", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "float fpul, fr%d", rn);
+ break;
+
+ case 3:
+ snprintf(buf, bufsiz, "ftrc fr%d, fpul", rn);
+ break;
+ }
+ break;
+
+ case 1:
+ switch (md) {
+ case 0:
+ snprintf(buf, bufsiz, "fneg fr%d", rn);
+ break;
+
+ case 1:
+ snprintf(buf, bufsiz, "fabs fr%d", rn);
+ break;
+
+ case 2:
+ snprintf(buf, bufsiz, "fsqrt fr%d", rn);
+ break;
+ }
+ break;
+
+ case 2:
+ switch (md) {
+ case 0:
+ case 1:
+ snprintf(buf, bufsiz, "fldi%d fr%d", md, rn);
+ break;
+ }
+ break;
+ } /* end of switch (type) */
+}
+
+static void
+f_fe(uint16_t *code, char *buf, size_t bufsiz)
+{
+ int rn, rm;
+
+ rn = (*code & 0x0f00) >> 8;
+ rm = (*code & 0x00f0) >> 4;
+
+ snprintf(buf, bufsiz, "fmac fr0, fr%d, fr%d", rm, rn);
+}
diff --git a/sys/arch/sh/sh/db_interface.c b/sys/arch/sh/sh/db_interface.c
new file mode 100644
index 00000000000..2fc8f75241d
--- /dev/null
+++ b/sys/arch/sh/sh/db_interface.c
@@ -0,0 +1,641 @@
+/* $OpenBSD: db_interface.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: db_interface.c,v 1.37 2006/09/06 00:11:49 uwe Exp $ */
+
+/*-
+ * Copyright (C) 2002 UCHIYAMA Yasushi. All rights reserved.
+ * Copyright (c) 2000 Tsubai Masanari. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/user.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <dev/cons.h>
+
+#include <machine/db_machdep.h>
+#include <ddb/db_run.h>
+#include <ddb/db_sym.h>
+
+#include <sh/ubcreg.h>
+
+db_regs_t ddb_regs; /* register state */
+
+
+#include <sh/cache.h>
+#include <sh/cache_sh3.h>
+#include <sh/cache_sh4.h>
+#include <sh/mmu.h>
+#include <sh/mmu_sh3.h>
+#include <sh/mmu_sh4.h>
+
+#include <ddb/db_command.h>
+#include <ddb/db_extern.h>
+#include <ddb/db_output.h>
+#include <ddb/db_run.h>
+#include <ddb/db_var.h>
+
+void kdb_printtrap(u_int, int);
+
+void db_tlbdump_cmd(db_expr_t, int, db_expr_t, char *);
+void __db_tlbdump_page_size_sh4(uint32_t);
+void __db_tlbdump_pfn(uint32_t);
+void db_cachedump_cmd(db_expr_t, int, db_expr_t, char *);
+
+void __db_cachedump_sh3(vaddr_t);
+void __db_cachedump_sh4(vaddr_t);
+
+void db_stackcheck_cmd(db_expr_t, int, db_expr_t, char *);
+void db_frame_cmd(db_expr_t, int, db_expr_t, char *);
+void __db_print_symbol(db_expr_t);
+char *__db_procname_by_asid(int);
+
+const struct db_command db_machine_command_table[] = {
+ { "tlb", db_tlbdump_cmd, 0, NULL },
+ { "cache", db_cachedump_cmd, 0, NULL },
+ { "frame", db_frame_cmd, 0, NULL },
+#ifdef KSTACK_DEBUG
+ { "stack", db_stackcheck_cmd, 0, NULL },
+#endif
+ { NULL }
+};
+
+int db_active;
+
+void
+kdb_printtrap(u_int type, int code)
+{
+ int i;
+ i = type >> 5;
+
+ db_printf("%s mode trap: ", type & 1 ? "user" : "kernel");
+ if (i >= exp_types)
+ db_printf("type 0x%03x", type & ~1);
+ else
+ db_printf("%s", exp_type[i]);
+
+ db_printf(" code = 0x%x\n", code);
+}
+
+int
+kdb_trap(int type, int code, db_regs_t *regs)
+{
+ extern label_t *db_recover;
+ int s;
+
+ switch (type) {
+ case EXPEVT_TRAPA: /* trapa instruction */
+ case EXPEVT_BREAK: /* UBC */
+ case -1: /* keyboard interrupt */
+ break;
+ default:
+ if (!db_panic && db_recover == NULL)
+ return 0;
+
+ kdb_printtrap(type, code);
+ if (db_recover != NULL) {
+ db_error("Faulted in DDB; continuing...\n");
+ /*NOTREACHED*/
+ }
+ }
+
+ /* XXX Should switch to kdb's own stack here. */
+
+ ddb_regs = *regs;
+
+ s = splhigh();
+ db_active++;
+ cnpollc(TRUE);
+ db_trap(type, code);
+ cnpollc(FALSE);
+ db_active--;
+ splx(s);
+
+ *regs = ddb_regs;
+
+ return 1;
+}
+
+#if 0
+void
+Debugger()
+{
+
+ __asm volatile("trapa %0" :: "i"(_SH_TRA_BREAK));
+}
+#endif
+
+#define M_BSR 0xf000
+#define I_BSR 0xb000
+#define M_BSRF 0xf0ff
+#define I_BSRF 0x0003
+#define M_JSR 0xf0ff
+#define I_JSR 0x400b
+#define M_RTS 0xffff
+#define I_RTS 0x000b
+#define M_RTE 0xffff
+#define I_RTE 0x002b
+
+boolean_t
+inst_call(int inst)
+{
+#if _BYTE_ORDER == BIG_ENDIAN
+ inst >>= 16;
+#endif
+ return (inst & M_BSR) == I_BSR || (inst & M_BSRF) == I_BSRF ||
+ (inst & M_JSR) == I_JSR;
+}
+
+boolean_t
+inst_return(int inst)
+{
+#if _BYTE_ORDER == BIG_ENDIAN
+ inst >>= 16;
+#endif
+ return (inst & M_RTS) == I_RTS;
+}
+
+boolean_t
+inst_trap_return(int inst)
+{
+#if _BYTE_ORDER == BIG_ENDIAN
+ inst >>= 16;
+#endif
+ return (inst & M_RTE) == I_RTE;
+}
+
+void
+db_set_single_step(db_regs_t *regs)
+{
+
+ _reg_write_2(SH_(BBRA), 0); /* disable break */
+ _reg_write_4(SH_(BARA), 0); /* break address */
+ _reg_write_1(SH_(BASRA), 0); /* break ASID */
+ _reg_write_1(SH_(BAMRA), 0x07); /* break always */
+ _reg_write_2(SH_(BRCR), 0x400); /* break after each execution */
+
+ regs->tf_ubc = 0x0014; /* will be written to BBRA */
+}
+
+void
+db_clear_single_step(db_regs_t *regs)
+{
+
+ regs->tf_ubc = 0;
+}
+
+#define ON(x, c) ((x) & (c) ? '|' : '.')
+
+/*
+ * MMU
+ */
+void
+db_tlbdump_cmd(db_expr_t addr, int have_addr, db_expr_t count,
+ char *modif)
+{
+ static const char *pr[] = { "_r", "_w", "rr", "ww" };
+ static const char title[] =
+ " VPN ASID PFN AREA VDCGWtPR SZ";
+ static const char title2[] =
+ " U/K U/K";
+ uint32_t r, e;
+ int i;
+#ifdef SH3
+ if (CPU_IS_SH3) {
+ /* MMU configuration. */
+ r = _reg_read_4(SH3_MMUCR);
+ db_printf("%s-mode, %s virtual storage mode\n",
+ r & SH3_MMUCR_IX
+ ? "ASID + VPN" : "VPN only",
+ r & SH3_MMUCR_SV ? "single" : "multiple");
+ i = _reg_read_4(SH3_PTEH) & SH3_PTEH_ASID_MASK;
+ db_printf("ASID=%d (%s)", i, __db_procname_by_asid(i));
+
+ db_printf("---TLB DUMP---\n%s\n%s\n", title, title2);
+ for (i = 0; i < SH3_MMU_WAY; i++) {
+ db_printf(" [way %d]\n", i);
+ for (e = 0; e < SH3_MMU_ENTRY; e++) {
+ uint32_t a;
+ /* address/data array common offset. */
+ a = (e << SH3_MMU_VPN_SHIFT) |
+ (i << SH3_MMU_WAY_SHIFT);
+
+ r = _reg_read_4(SH3_MMUAA | a);
+ if (r == 0) {
+ db_printf("---------- - --- ----------"
+ " - ----x -- --\n");
+ } else {
+ vaddr_t va;
+ int asid;
+ asid = r & SH3_MMUAA_D_ASID_MASK;
+ r &= SH3_MMUAA_D_VPN_MASK_1K;
+ va = r | (e << SH3_MMU_VPN_SHIFT);
+ db_printf("0x%08lx %c %3d", va,
+ (int)va < 0 ? 'K' : 'U', asid);
+
+ r = _reg_read_4(SH3_MMUDA | a);
+ __db_tlbdump_pfn(r);
+
+ db_printf(" %c%c%c%cx %s %2dK\n",
+ ON(r, SH3_MMUDA_D_V),
+ ON(r, SH3_MMUDA_D_D),
+ ON(r, SH3_MMUDA_D_C),
+ ON(r, SH3_MMUDA_D_SH),
+ pr[(r & SH3_MMUDA_D_PR_MASK) >>
+ SH3_MMUDA_D_PR_SHIFT],
+ r & SH3_MMUDA_D_SZ ? 4 : 1);
+ }
+ }
+ }
+ }
+#endif /* SH3 */
+#ifdef SH4
+ if (CPU_IS_SH4) {
+ /* MMU configuration */
+ r = _reg_read_4(SH4_MMUCR);
+ db_printf("%s virtual storage mode, SQ access: (kernel%s)\n",
+ r & SH3_MMUCR_SV ? "single" : "multiple",
+ r & SH4_MMUCR_SQMD ? "" : "/user");
+ db_printf("random counter limit=%d\n",
+ (r & SH4_MMUCR_URB_MASK) >> SH4_MMUCR_URB_SHIFT);
+
+ i = _reg_read_4(SH4_PTEH) & SH4_PTEH_ASID_MASK;
+ db_printf("ASID=%d (%s)", i, __db_procname_by_asid(i));
+
+ /* Dump ITLB */
+ db_printf("---ITLB DUMP ---\n%s TC SA\n%s\n", title, title2);
+ for (i = 0; i < 4; i++) {
+ e = i << SH4_ITLB_E_SHIFT;
+
+ r = _reg_read_4(SH4_ITLB_AA | e);
+ db_printf("0x%08x %3d",
+ r & SH4_ITLB_AA_VPN_MASK,
+ r & SH4_ITLB_AA_ASID_MASK);
+
+ r = _reg_read_4(SH4_ITLB_DA1 | e);
+ __db_tlbdump_pfn(r);
+ db_printf(" %c_%c%c_ %s ",
+ ON(r, SH4_ITLB_DA1_V),
+ ON(r, SH4_ITLB_DA1_C),
+ ON(r, SH4_ITLB_DA1_SH),
+ pr[(r & SH4_ITLB_DA1_PR) >>
+ SH4_UTLB_DA1_PR_SHIFT]);
+ __db_tlbdump_page_size_sh4(r);
+
+#if 0 /* XXX: causes weird effects on landisk */
+ r = _reg_read_4(SH4_ITLB_DA2 | e);
+ db_printf(" %c %d\n",
+ ON(r, SH4_ITLB_DA2_TC),
+ r & SH4_ITLB_DA2_SA_MASK);
+#else
+ db_printf("\n");
+#endif
+ }
+
+ /* Dump UTLB */
+ db_printf("---UTLB DUMP---\n%s TC SA\n%s\n", title, title2);
+ for (i = 0; i < 64; i++) {
+ e = i << SH4_UTLB_E_SHIFT;
+
+ r = _reg_read_4(SH4_UTLB_AA | e);
+ db_printf("0x%08x %3d",
+ r & SH4_UTLB_AA_VPN_MASK,
+ r & SH4_UTLB_AA_ASID_MASK);
+
+ r = _reg_read_4(SH4_UTLB_DA1 | e);
+ __db_tlbdump_pfn(r);
+ db_printf(" %c%c%c%c%c %s ",
+ ON(r, SH4_UTLB_DA1_V),
+ ON(r, SH4_UTLB_DA1_D),
+ ON(r, SH4_UTLB_DA1_C),
+ ON(r, SH4_UTLB_DA1_SH),
+ ON(r, SH4_UTLB_DA1_WT),
+ pr[(r & SH4_UTLB_DA1_PR_MASK) >>
+ SH4_UTLB_DA1_PR_SHIFT]
+ );
+ __db_tlbdump_page_size_sh4(r);
+
+#if 0 /* XXX: causes weird effects on landisk */
+ r = _reg_read_4(SH4_UTLB_DA2 | e);
+ db_printf(" %c %d\n",
+ ON(r, SH4_UTLB_DA2_TC),
+ r & SH4_UTLB_DA2_SA_MASK);
+#else
+ db_printf("\n");
+#endif
+ }
+ }
+#endif /* SH4 */
+}
+
+void
+__db_tlbdump_pfn(uint32_t r)
+{
+ uint32_t pa = (r & SH3_MMUDA_D_PPN_MASK);
+
+ db_printf(" 0x%08x %d", pa, (pa >> 26) & 7);
+}
+
+char *
+__db_procname_by_asid(int asid)
+{
+ static char notfound[] = "---";
+ struct proc *p;
+
+ LIST_FOREACH(p, &allproc, p_list) {
+ if (p->p_vmspace->vm_map.pmap->pm_asid == asid)
+ return (p->p_comm);
+ }
+
+ return (notfound);
+}
+
+#ifdef SH4
+void
+__db_tlbdump_page_size_sh4(uint32_t r)
+{
+ switch (r & SH4_PTEL_SZ_MASK) {
+ case SH4_PTEL_SZ_1K:
+ db_printf(" 1K");
+ break;
+ case SH4_PTEL_SZ_4K:
+ db_printf(" 4K");
+ break;
+ case SH4_PTEL_SZ_64K:
+ db_printf("64K");
+ break;
+ case SH4_PTEL_SZ_1M:
+ db_printf(" 1M");
+ break;
+ }
+}
+#endif /* SH4 */
+
+/*
+ * CACHE
+ */
+void
+db_cachedump_cmd(db_expr_t addr, int have_addr, db_expr_t count,
+ char *modif)
+{
+#ifdef SH3
+ if (CPU_IS_SH3)
+ __db_cachedump_sh3(have_addr ? addr : 0);
+#endif
+#ifdef SH4
+ if (CPU_IS_SH4)
+ __db_cachedump_sh4(have_addr ? addr : 0);
+#endif
+}
+
+#ifdef SH3
+void
+__db_cachedump_sh3(vaddr_t va_start)
+{
+ uint32_t r;
+ vaddr_t va, va_end, cca;
+ int entry, way;
+
+ RUN_P2;
+ /* disable cache */
+ _reg_write_4(SH3_CCR,
+ _reg_read_4(SH3_CCR) & ~SH3_CCR_CE);
+
+ if (va_start) {
+ va = va_start & ~(sh_cache_line_size - 1);
+ va_end = va + sh_cache_line_size;
+ } else {
+ va = 0;
+ va_end = sh_cache_way_size;
+ }
+
+ db_printf("%d-way, way-size=%dB, way-shift=%d, entry-mask=%08x, "
+ "line-size=%dB \n", sh_cache_ways, sh_cache_way_size,
+ sh_cache_way_shift, sh_cache_entry_mask, sh_cache_line_size);
+ db_printf("Entry Way 0 UV Way 1 UV Way 2 UV Way 3 UV\n");
+ for (; va < va_end; va += sh_cache_line_size) {
+ entry = va & sh_cache_entry_mask;
+ cca = SH3_CCA | entry;
+ db_printf(" %3d ", entry >> CCA_ENTRY_SHIFT);
+ for (way = 0; way < sh_cache_ways; way++) {
+ r = _reg_read_4(cca | (way << sh_cache_way_shift));
+ db_printf("%08x %c%c ", r & CCA_TAGADDR_MASK,
+ ON(r, CCA_U), ON(r, CCA_V));
+ }
+ db_printf("\n");
+ }
+
+ /* enable cache */
+ _reg_bset_4(SH3_CCR, SH3_CCR_CE);
+ sh_icache_sync_all();
+
+ RUN_P1;
+}
+#endif /* SH3 */
+
+#ifdef SH4
+void
+__db_cachedump_sh4(vaddr_t va)
+{
+ uint32_t r, e;
+ int i, istart, iend;
+
+ RUN_P2; /* must access from P2 */
+
+ /* disable I/D-cache */
+ _reg_write_4(SH4_CCR,
+ _reg_read_4(SH4_CCR) & ~(SH4_CCR_ICE | SH4_CCR_OCE));
+
+ if (va) {
+ istart = ((va & CCIA_ENTRY_MASK) >> CCIA_ENTRY_SHIFT) & ~3;
+ iend = istart + 4;
+ } else {
+ istart = 0;
+ iend = SH4_ICACHE_SIZE / SH4_CACHE_LINESZ;
+ }
+
+ db_printf("[I-cache]\n");
+ db_printf(" Entry V V V V\n");
+ for (i = istart; i < iend; i++) {
+ if ((i & 3) == 0)
+ db_printf("\n[%3d-%3d] ", i, i + 3);
+ r = _reg_read_4(SH4_CCIA | (i << CCIA_ENTRY_SHIFT));
+ db_printf("%08x _%c ", r & CCIA_TAGADDR_MASK, ON(r, CCIA_V));
+ }
+
+ db_printf("\n[D-cache]\n");
+ db_printf(" Entry UV UV UV UV\n");
+ for (i = istart; i < iend; i++) {
+ if ((i & 3) == 0)
+ db_printf("\n[%3d-%3d] ", i, i + 3);
+ e = (i << CCDA_ENTRY_SHIFT);
+ r = _reg_read_4(SH4_CCDA | e);
+ db_printf("%08x %c%c ", r & CCDA_TAGADDR_MASK, ON(r, CCDA_U),
+ ON(r, CCDA_V));
+
+ }
+ db_printf("\n");
+
+ _reg_write_4(SH4_CCR,
+ _reg_read_4(SH4_CCR) | SH4_CCR_ICE | SH4_CCR_OCE);
+ sh_icache_sync_all();
+
+ RUN_P1;
+}
+#endif /* SH4 */
+
+#undef ON
+
+void
+db_frame_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
+{
+ struct switchframe *sf = &curpcb->pcb_sf;
+ struct trapframe *tf, *tftop;
+
+ /* Print switch frame */
+ db_printf("[switch frame]\n");
+
+#define SF(x) db_printf("sf_" #x "\t\t0x%08x\t", sf->sf_ ## x); \
+ __db_print_symbol(sf->sf_ ## x)
+
+ SF(sr);
+ SF(r15);
+ SF(r14);
+ SF(r13);
+ SF(r12);
+ SF(r11);
+ SF(r10);
+ SF(r9);
+ SF(r8);
+ SF(pr);
+ db_printf("sf_r6_bank\t0x%08x\n", sf->sf_r6_bank);
+ db_printf("sf_r7_bank\t0x%08x\n", sf->sf_r7_bank);
+
+
+ /* Print trap frame stack */
+ db_printf("[trap frame]\n");
+
+ __asm("stc r6_bank, %0" : "=r"(tf));
+ tftop = (struct trapframe *)((vaddr_t)curpcb + PAGE_SIZE);
+
+ for (; tf != tftop; tf++) {
+ db_printf("-- %p-%p --\n", tf, tf + 1);
+ db_printf("tf_expevt\t0x%08x\n", tf->tf_expevt);
+
+#define TF(x) db_printf("tf_" #x "\t\t0x%08x\t", tf->tf_ ## x); \
+ __db_print_symbol(tf->tf_ ## x)
+
+ TF(ubc);
+ TF(spc);
+ TF(ssr);
+ TF(macl);
+ TF(mach);
+ TF(pr);
+ TF(r13);
+ TF(r12);
+ TF(r11);
+ TF(r10);
+ TF(r9);
+ TF(r8);
+ TF(r7);
+ TF(r6);
+ TF(r5);
+ TF(r4);
+ TF(r3);
+ TF(r2);
+ TF(r1);
+ TF(r0);
+ TF(r15);
+ TF(r14);
+ }
+#undef SF
+#undef TF
+}
+
+void
+__db_print_symbol(db_expr_t value)
+{
+ char *name;
+ db_expr_t offset;
+
+ db_find_sym_and_offset((db_addr_t)value, &name, &offset);
+ if (name != NULL && offset <= db_maxoff && offset != value)
+ db_printsym(value, DB_STGY_ANY, db_printf);
+
+ db_printf("\n");
+}
+
+#ifdef KSTACK_DEBUG
+/*
+ * Stack overflow check
+ */
+void
+db_stackcheck_cmd(db_expr_t addr, int have_addr, db_expr_t count,
+ char *modif)
+{
+ struct proc *p;
+ struct user *u;
+ struct pcb *pcb;
+ uint32_t *t32;
+ uint8_t *t8;
+ int i, j;
+
+#define MAX_STACK (USPACE - PAGE_SIZE)
+#define MAX_FRAME (PAGE_SIZE - sizeof(struct user))
+
+ db_printf("stack max: %d byte, frame max %d byte,"
+ " sizeof(struct trapframe) %d byte\n", MAX_STACK, MAX_FRAME,
+ sizeof(struct trapframe));
+ db_printf(" PID.LID "
+ "stack top max used frame top max used"
+ " nest\n");
+
+ LIST_FOREACH(p, &allproc, p_list) {
+ u = p->p_addr;
+ pcb = &u->u_pcb;
+ /* stack */
+ t32 = (uint32_t *)(pcb->pcb_sf.sf_r7_bank - MAX_STACK);
+ for (i = 0; *t32++ == 0xa5a5a5a5; i++)
+ continue;
+ i = MAX_STACK - i * sizeof(int);
+
+ /* frame */
+ t8 = (uint8_t *)((vaddr_t)pcb + PAGE_SIZE - MAX_FRAME);
+ for (j = 0; *t8++ == 0x5a; j++)
+ continue;
+ j = MAX_FRAME - j;
+
+ db_printf("%6d 0x%08x %6d (%3d%%) 0x%08lx %6d (%3d%%) %d %s\n",
+ p->p_lid,
+ pcb->pcb_sf.sf_r7_bank, i, i * 100 / MAX_STACK,
+ (vaddr_t)pcb + PAGE_SIZE, j, j * 100 / MAX_FRAME,
+ j / sizeof(struct trapframe),
+ p->p_comm);
+ }
+#undef MAX_STACK
+#undef MAX_FRAME
+}
+#endif /* KSTACK_DEBUG */
diff --git a/sys/arch/sh/sh/db_memrw.c b/sys/arch/sh/sh/db_memrw.c
new file mode 100644
index 00000000000..978c8c37005
--- /dev/null
+++ b/sys/arch/sh/sh/db_memrw.c
@@ -0,0 +1,94 @@
+/* $OpenBSD: db_memrw.c,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: db_memrw.c,v 1.8 2006/02/24 00:57:19 uwe Exp $ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ *
+ * db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
+ */
+
+/*
+ * Routines to read and write memory on behalf of the debugger, used
+ * by DDB.
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/stdint.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/db_machdep.h>
+
+#include <ddb/db_access.h>
+
+/*
+ * Read bytes from kernel address space for debugger.
+ */
+void
+db_read_bytes(vaddr_t addr, size_t size, char *data)
+{
+ char *src = (char *)addr;
+
+ /* properly aligned 4-byte */
+ if (size == 4 && ((addr & 3) == 0) && (((uintptr_t)data & 3) == 0)) {
+ *(uint32_t *)data = *(uint32_t *)src;
+ return;
+ }
+
+ /* properly aligned 2-byte */
+ if (size == 2 && ((addr & 1) == 0) && (((uintptr_t)data & 1) == 0)) {
+ *(uint16_t *)data = *(uint16_t *)src;
+ return;
+ }
+
+ while (size-- > 0)
+ *data++ = *src++;
+}
+
+/*
+ * Write bytes to kernel address space for debugger.
+ */
+void
+db_write_bytes(vaddr_t addr, size_t size, char *data)
+{
+ char *dst = (char *)addr;
+
+ /* properly aligned 4-byte */
+ if (size == 4 && ((addr & 3) == 0) && (((uintptr_t)data & 3) == 0)) {
+ *(uint32_t *)dst = *(const uint32_t *)data;
+ return;
+ }
+
+ /* properly aligned 2-byte */
+ if (size == 2 && ((addr & 1) == 0) && (((uintptr_t)data & 1) == 0)) {
+ *(uint16_t *)dst = *(const uint16_t *)data;
+ return;
+ }
+
+ while (size-- > 0)
+ *dst++ = *data++;
+}
diff --git a/sys/arch/sh/sh/db_trace.c b/sys/arch/sh/sh/db_trace.c
new file mode 100644
index 00000000000..8228c26bf46
--- /dev/null
+++ b/sys/arch/sh/sh/db_trace.c
@@ -0,0 +1,225 @@
+/* $OpenBSD: db_trace.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: db_trace.c,v 1.19 2006/01/21 22:10:59 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2000 Tsubai Masanari. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/db_machdep.h>
+
+#include <ddb/db_access.h>
+#include <ddb/db_interface.h>
+#include <ddb/db_output.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_variables.h>
+
+#ifdef TRACE_DEBUG
+# define DPRINTF printf
+#else
+# define DPRINTF while (/* CONSTCOND */ 0) printf
+#endif
+
+extern char start[], etext[];
+void db_nextframe(db_addr_t, db_addr_t *, db_addr_t *);
+
+struct db_variable db_regs[] = {
+ { "r0", (long *)&ddb_regs.tf_r0, FCN_NULL },
+ { "r1", (long *)&ddb_regs.tf_r1, FCN_NULL },
+ { "r2", (long *)&ddb_regs.tf_r2, FCN_NULL },
+ { "r3", (long *)&ddb_regs.tf_r3, FCN_NULL },
+ { "r4", (long *)&ddb_regs.tf_r4, FCN_NULL },
+ { "r5", (long *)&ddb_regs.tf_r5, FCN_NULL },
+ { "r6", (long *)&ddb_regs.tf_r6, FCN_NULL },
+ { "r7", (long *)&ddb_regs.tf_r7, FCN_NULL },
+ { "r8", (long *)&ddb_regs.tf_r8, FCN_NULL },
+ { "r9", (long *)&ddb_regs.tf_r9, FCN_NULL },
+ { "r10", (long *)&ddb_regs.tf_r10, FCN_NULL },
+ { "r11", (long *)&ddb_regs.tf_r11, FCN_NULL },
+ { "r12", (long *)&ddb_regs.tf_r12, FCN_NULL },
+ { "r13", (long *)&ddb_regs.tf_r13, FCN_NULL },
+ { "r14", (long *)&ddb_regs.tf_r14, FCN_NULL },
+ { "r15", (long *)&ddb_regs.tf_r15, FCN_NULL },
+ { "pr", (long *)&ddb_regs.tf_pr, FCN_NULL },
+ { "spc", (long *)&ddb_regs.tf_spc, FCN_NULL },
+ { "ssr", (long *)&ddb_regs.tf_ssr, FCN_NULL },
+ { "mach", (long *)&ddb_regs.tf_mach, FCN_NULL },
+ { "macl", (long *)&ddb_regs.tf_macl, FCN_NULL },
+};
+
+struct db_variable *db_eregs =
+ db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+
+void
+db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count,
+ char *modif, int (*print)(const char *, ...))
+{
+ db_addr_t callpc, frame, lastframe;
+ uint32_t vbr;
+
+ __asm volatile("stc vbr, %0" : "=r"(vbr));
+
+ frame = ddb_regs.tf_r14;
+ callpc = ddb_regs.tf_spc;
+
+ lastframe = 0;
+ while (count > 0 && frame != 0) {
+ /* Are we crossing a trap frame? */
+ if ((callpc & ~PAGE_MASK) == vbr) {
+ struct trapframe *tf = (void *)frame;
+
+ frame = tf->tf_r14;
+ callpc = tf->tf_spc;
+
+ (*print)("<EXPEVT %03x; SSR=%08x> at ",
+ tf->tf_expevt, tf->tf_ssr);
+ db_printsym(callpc, DB_STGY_PROC, print);
+ (*print)("\n");
+
+ /* XXX: don't venture into the userland yet */
+ if ((tf->tf_ssr & PSL_MD) == 0)
+ break;
+ } else {
+ char *name;
+ db_expr_t offset;
+ db_sym_t sym;
+
+
+ DPRINTF(" (1)newpc 0x%lx, newfp 0x%lx\n",
+ callpc, frame);
+
+ sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);
+ db_symbol_values(sym, &name, NULL);
+
+ if (lastframe == 0 && sym == 0) {
+ printf("symbol not found\n");
+ break;
+ }
+
+ db_nextframe(callpc - offset, &frame, &callpc);
+ DPRINTF(" (2)newpc 0x%lx, newfp 0x%lx\n",
+ callpc, frame);
+
+ if (callpc == 0 && lastframe == 0)
+ callpc = (db_addr_t)ddb_regs.tf_pr;
+ DPRINTF(" (3)newpc 0x%lx, newfp 0x%lx\n",
+ callpc, frame);
+
+ (*print)("%s() at ", name ? name : "");
+ db_printsym(callpc, DB_STGY_PROC, print);
+ (*print)("\n");
+ }
+
+ count--;
+ lastframe = frame;
+ }
+}
+
+void
+db_nextframe(
+ db_addr_t pc, /* in: entry address of current function */
+ db_addr_t *fp, /* in: current fp, out: parent fp */
+ db_addr_t *pr) /* out: parent pr */
+{
+ int *frame = (void *)*fp;
+ int i, inst;
+ int depth, prdepth, fpdepth;
+
+ depth = 0;
+ prdepth = fpdepth = -1;
+
+ if (pc < (db_addr_t)start || pc > (db_addr_t)etext)
+ goto out;
+
+ for (i = 0; i < 30; i++) {
+ inst = db_get_value(pc, 2, FALSE);
+ pc += 2;
+
+ if (inst == 0x6ef3) /* mov r15,r14 -- end of prologue */
+ break;
+
+ if (inst == 0x4f22) { /* sts.l pr,@-r15 */
+ prdepth = depth;
+ depth++;
+ continue;
+ }
+ if (inst == 0x2fe6) { /* mov.l r14,@-r15 */
+ fpdepth = depth;
+ depth++;
+ continue;
+ }
+ if ((inst & 0xff0f) == 0x2f06) { /* mov.l r?,@-r15 */
+ depth++;
+ continue;
+ }
+ if ((inst & 0xff00) == 0x7f00) { /* add #n,r15 */
+ int8_t n = inst & 0xff;
+
+ if (n >= 0) {
+ printf("add #n,r15 (n > 0)\n");
+ break;
+ }
+
+ depth += -n/4;
+ continue;
+ }
+ if ((inst & 0xf000) == 0x9000) {
+ if (db_get_value(pc, 2, FALSE) == 0x3f38) {
+ /* "mov #n,r3; sub r3,r15" */
+ unsigned int disp = (int)(inst & 0xff);
+ int r3;
+
+ r3 = (int)*(unsigned short *)(pc + (4 - 2)
+ + (disp << 1));
+ if ((r3 & 0x00008000) == 0)
+ r3 &= 0x0000ffff;
+ else
+ r3 |= 0xffff0000;
+ depth += (r3 / 4);
+
+ pc += 2;
+ continue;
+ }
+ }
+
+#ifdef TRACE_DEBUG
+ printf("unknown instruction in prologue\n");
+ db_disasm(pc - 2, 0);
+#endif
+ }
+
+ out:
+ if (fpdepth != -1)
+ *fp = frame[depth - fpdepth - 1];
+ else
+ *fp = 0;
+
+ if (prdepth != -1)
+ *pr = frame[depth - prdepth - 1];
+ else
+ *pr = 0;
+}
diff --git a/sys/arch/sh/sh/devreg.c b/sys/arch/sh/sh/devreg.c
new file mode 100644
index 00000000000..ec1df3bbbe1
--- /dev/null
+++ b/sys/arch/sh/sh/devreg.c
@@ -0,0 +1,167 @@
+/* $OpenBSD: devreg.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: devreg.c,v 1.6 2006/03/04 01:13:35 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ */
+
+#include <sys/param.h>
+
+#include <sh/cache_sh3.h>
+#include <sh/cache_sh4.h>
+#include <sh/mmu_sh3.h>
+#include <sh/mmu_sh4.h>
+#include <sh/trap.h>
+
+#include <sh/ubcreg.h>
+#include <sh/rtcreg.h>
+#include <sh/tmureg.h>
+
+/* MMU */
+uint32_t __sh_PTEH;
+uint32_t __sh_TTB;
+uint32_t __sh_TEA;
+uint32_t __sh_TRA;
+uint32_t __sh_EXPEVT;
+uint32_t __sh_INTEVT;
+
+/* UBC */
+uint32_t __sh_BARA;
+uint32_t __sh_BAMRA;
+uint32_t __sh_BASRA;
+uint32_t __sh_BBRA;
+uint32_t __sh_BARB;
+uint32_t __sh_BAMRB;
+uint32_t __sh_BASRB;
+uint32_t __sh_BBRB;
+uint32_t __sh_BDRB;
+uint32_t __sh_BDMRB;
+uint32_t __sh_BRCR;
+
+/* RTC */
+uint32_t __sh_R64CNT;
+uint32_t __sh_RSECCNT;
+uint32_t __sh_RMINCNT;
+uint32_t __sh_RHRCNT;
+uint32_t __sh_RWKCNT;
+uint32_t __sh_RDAYCNT;
+uint32_t __sh_RMONCNT;
+uint32_t __sh_RYRCNT;
+uint32_t __sh_RSECAR;
+uint32_t __sh_RMINAR;
+uint32_t __sh_RHRAR;
+uint32_t __sh_RWKAR;
+uint32_t __sh_RDAYAR;
+uint32_t __sh_RMONAR;
+uint32_t __sh_RCR1;
+uint32_t __sh_RCR2;
+
+/* TMU */
+uint32_t __sh_TOCR;
+uint32_t __sh_TSTR;
+uint32_t __sh_TCOR0;
+uint32_t __sh_TCNT0;
+uint32_t __sh_TCR0;
+uint32_t __sh_TCOR1;
+uint32_t __sh_TCNT1;
+uint32_t __sh_TCR1;
+uint32_t __sh_TCOR2;
+uint32_t __sh_TCNT2;
+uint32_t __sh_TCR2;
+uint32_t __sh_TCPR2;
+
+#define SH3REG(x) __sh_ ## x = SH3_ ## x
+#define SH4REG(x) __sh_ ## x = SH4_ ## x
+
+#define SHREG(x) \
+do { \
+/* Exception */ \
+SH ## x ## REG(TRA); \
+SH ## x ## REG(EXPEVT); \
+SH ## x ## REG(INTEVT); \
+/* UBC */ \
+SH ## x ## REG(BARA); \
+SH ## x ## REG(BAMRA); \
+SH ## x ## REG(BASRA); \
+SH ## x ## REG(BBRA); \
+SH ## x ## REG(BARB); \
+SH ## x ## REG(BAMRB); \
+SH ## x ## REG(BASRB); \
+SH ## x ## REG(BBRB); \
+SH ## x ## REG(BDRB); \
+SH ## x ## REG(BDMRB); \
+SH ## x ## REG(BRCR); \
+/* MMU */ \
+SH ## x ## REG(PTEH); \
+SH ## x ## REG(TEA); \
+SH ## x ## REG(TTB); \
+/* RTC */ \
+SH ## x ## REG(R64CNT); \
+SH ## x ## REG(RSECCNT); \
+SH ## x ## REG(RMINCNT); \
+SH ## x ## REG(RHRCNT); \
+SH ## x ## REG(RWKCNT); \
+SH ## x ## REG(RDAYCNT); \
+SH ## x ## REG(RMONCNT); \
+SH ## x ## REG(RYRCNT); \
+SH ## x ## REG(RSECAR); \
+SH ## x ## REG(RMINAR); \
+SH ## x ## REG(RHRAR); \
+SH ## x ## REG(RWKAR); \
+SH ## x ## REG(RDAYAR); \
+SH ## x ## REG(RMONAR); \
+SH ## x ## REG(RCR1); \
+SH ## x ## REG(RCR2); \
+/* TMU */ \
+SH ## x ## REG(TOCR); \
+SH ## x ## REG(TSTR); \
+SH ## x ## REG(TCOR0); \
+SH ## x ## REG(TCNT0); \
+SH ## x ## REG(TCR0); \
+SH ## x ## REG(TCOR1); \
+SH ## x ## REG(TCNT1); \
+SH ## x ## REG(TCR1); \
+SH ## x ## REG(TCOR2); \
+SH ## x ## REG(TCNT2); \
+SH ## x ## REG(TCR2); \
+SH ## x ## REG(TCPR2); \
+} while (/*CONSTCOND*/0)
+
+void
+sh_devreg_init()
+{
+ if (CPU_IS_SH3)
+ SHREG(3);
+
+ if (CPU_IS_SH4)
+ SHREG(4);
+}
diff --git a/sys/arch/sh/sh/genassym.cf b/sys/arch/sh/sh/genassym.cf
new file mode 100644
index 00000000000..52c6fb4a19f
--- /dev/null
+++ b/sys/arch/sh/sh/genassym.cf
@@ -0,0 +1,120 @@
+# $OpenBSD: genassym.cf,v 1.1 2006/10/06 21:02:55 miod Exp $
+# $NetBSD: genassym.cf,v 1.10 2005/12/11 12:19:00 christos Exp $
+
+#-
+# Copyright (c) 2002 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. 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.
+#
+
+include <sys/param.h>
+include <sys/proc.h>
+include <sys/signal.h>
+include <sys/mbuf.h>
+include <sys/user.h>
+include <sys/errno.h>
+include <uvm/uvm_extern.h>
+include <sh/locore.h>
+include <sh/vmparam.h>
+
+struct trapframe
+define TF_SIZE sizeof(struct trapframe)
+member tf_expevt
+member tf_ubc
+member tf_spc
+member tf_ssr
+member tf_macl
+member tf_mach
+member tf_pr
+member tf_r14
+member tf_r13
+member tf_r12
+member tf_r11
+member tf_r10
+member tf_r9
+member tf_r8
+member tf_r7
+member tf_r6
+member tf_r5
+member tf_r4
+member tf_r3
+member tf_r2
+member tf_r1
+member tf_r0
+member tf_r15
+
+struct proc
+member p_addr
+member p_back
+member p_forw
+member p_stat
+member p_wchan
+member P_MD_UPTE p_md.md_upte
+member P_MD_PCB p_md.md_pcb
+
+struct switchframe
+define SF_SIZE sizeof(struct switchframe)
+member sf_sr
+member sf_r15
+member sf_r14
+member sf_r13
+member sf_r12
+member sf_r10
+member sf_r9
+member sf_r8
+member sf_pr
+member sf_r6_bank
+member sf_r7_bank
+
+struct sigcontext
+member SC_EFLAGS sc_ssr
+
+struct pcb
+member pcb_onfault
+member pcb_faultbail
+
+export SONPROC
+export SRUN
+
+struct uvmexp UVMEXP_
+member intrs
+
+export VM_MAXUSER_ADDRESS
+
+export EFAULT
+export ENAMETOOLONG
+
+#
+# in_cksum.S
+#
+struct mbuf
+member m_data
+member m_len
+member m_next
diff --git a/sys/arch/sh/sh/in_cksum.S b/sys/arch/sh/sh/in_cksum.S
new file mode 100644
index 00000000000..f03ddb3bf96
--- /dev/null
+++ b/sys/arch/sh/sh/in_cksum.S
@@ -0,0 +1,279 @@
+/* $OpenBSD: in_cksum.S,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: in_cksum.S,v 1.10 2006/04/11 23:45:13 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2000 SHIMIZU Ryo <ryo@misakimix.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+#include "assym.h"
+
+
+#define reg_tmp0 r0
+#define reg_byte_swapped r1
+#define reg_mlen r2
+#define reg_tmp3 r3
+#define reg_m r4
+#define reg_len r5
+#define reg_sum r6
+#define reg_w r7
+
+
+#define REDUCE \
+ swap.w reg_sum,reg_tmp0 ; \
+ extu.w reg_sum,reg_sum ; \
+ extu.w reg_tmp0,reg_tmp0 ; \
+ add reg_tmp0,reg_sum
+
+#define ROL \
+ shll8 reg_sum
+
+#ifndef __LITTLE_ENDIAN__
+#define ADDB \
+ mov.b @reg_w+,reg_tmp0 ; \
+ ROL ; \
+ extu.b reg_tmp0,reg_tmp0 ; \
+ add reg_tmp0,reg_sum ; \
+ not reg_byte_swapped,reg_byte_swapped
+#else
+#define ADDB \
+ mov.b @reg_w+,reg_tmp0 ; \
+ extu.b reg_tmp0,reg_tmp0 ; \
+ add reg_tmp0,reg_sum ; \
+ ROL ; \
+ not reg_byte_swapped,reg_byte_swapped
+#endif
+
+
+#define ADDS \
+ mov.w @reg_w+,reg_tmp0 ; \
+ extu.w reg_tmp0,reg_tmp0 ; \
+ add reg_tmp0,reg_sum
+
+#define ADDCL \
+ mov.l @reg_w+,reg_tmp0 ; \
+ addc reg_tmp0,reg_sum
+
+#define FORWARD1 \
+ add #-1,reg_mlen
+
+#define FORWARD2 \
+ add #-2,reg_mlen
+
+
+/*
+ * LINTSTUB: include <sys/param.h>
+ * LINTSTUB: include <sys/mbuf.h>
+ *
+ * LINTSTUB: Func: int in_cksum(struct mbuf *m, int len);
+ */
+ENTRY(in_cksum)
+ sts.l pr,@-sp
+
+
+ mov #0,reg_sum
+ mov #0,reg_byte_swapped
+
+
+ tst reg_len,reg_len
+ bt/s mbuf_loop_done
+mbuf_loop:
+ tst reg_m,reg_m
+ bt out_of_mbufs
+
+ mov.l @(M_LEN,reg_m),reg_mlen
+ tst reg_mlen,reg_mlen
+ bt/s mbuf_loop_continue
+ mov.l @(M_DATA,reg_m),reg_w
+
+
+ cmp/ge reg_mlen,reg_len
+ bt 1f
+ mov reg_len,reg_mlen
+1:
+ sub reg_mlen,reg_len
+
+
+ mov reg_w,reg_tmp0
+ tst #1,reg_tmp0
+ bt/s 1f
+ REDUCE /* 1st instruction break only reg_tmp0(r0) */
+ ADDB
+ FORWARD1
+1:
+
+
+ mov #1,reg_tmp0
+ cmp/gt reg_tmp0,reg_mlen
+ bf/s 1f
+ mov reg_w,reg_tmp0
+ tst #2,reg_tmp0
+ bt/s 1f
+ REDUCE /* 1st instruction break only reg_tmp0(r0) */
+ ADDS
+ FORWARD2
+1:
+
+
+
+ mov #127,reg_tmp0
+ cmp/hi reg_tmp0,reg_mlen
+ bf 1f
+
+do_cksum128:
+ bsr cksum128
+ nop
+
+ mov #127,reg_tmp0
+ cmp/hi reg_tmp0,reg_mlen
+ bt do_cksum128
+1:
+
+
+ bsr cksum128mod
+ nop
+
+ REDUCE
+
+ mov #1,reg_tmp0
+ cmp/gt reg_tmp0,reg_mlen
+ bf 1f
+ ADDS
+ FORWARD2
+1:
+
+ mov reg_mlen,r0
+ tst #1,r0
+ bt 1f
+ ADDB
+1:
+
+
+mbuf_loop_continue:
+ mov.l @(M_NEXT,reg_m),reg_m
+
+ tst reg_len,reg_len
+ bf/s mbuf_loop
+mbuf_loop_done:
+
+
+ tst reg_byte_swapped,reg_byte_swapped
+ bt/s 1f
+ REDUCE /* 1st instruction break only reg_tmp0(r0) */
+ ROL
+1:
+
+ REDUCE
+ REDUCE
+
+in_cksum_return:
+ not reg_sum,r0
+ lds.l @sp+,pr
+ rts
+ extu.w r0,r0
+
+
+out_of_mbufs:
+ mova .L_message_out_of_data,reg_tmp0
+ mov.l .L_printf,reg_tmp3
+
+ mov.l reg_sum,@-sp /* save: call clobbered register */
+
+ jsr @reg_tmp3
+ mov reg_tmp0,r4
+
+ bra in_cksum_return
+ mov.l @sp+,reg_sum /* restore */
+
+ .align 2
+.L_printf:
+ .long _C_LABEL(printf)
+
+ .align 2 /* mova target */
+.L_message_out_of_data:
+ .asciz "cksum: out of data (%d byte short)\n"
+
+ SET_ENTRY_SIZE(in_cksum)
+
+
+ .align 2
+cksum128mod:
+ mov reg_mlen,reg_tmp0
+ and #124,reg_tmp0
+ sub reg_tmp0,reg_mlen
+
+ mov.l .L_cksum128_tail_p,reg_tmp3
+ sub reg_tmp0,reg_tmp3
+ jmp @reg_tmp3
+ clrt
+
+ .align 2
+.L_cksum128_tail_p:
+ .long cksum128_tail
+
+
+ .align 2
+cksum128:
+ add #-128,reg_mlen
+ clrt
+
+cksum128_unroll:
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+ ADDCL
+cksum128_tail:
+ mov #0,reg_tmp0
+ rts
+ addc reg_tmp0,reg_sum
diff --git a/sys/arch/sh/sh/interrupt.c b/sys/arch/sh/sh/interrupt.c
new file mode 100644
index 00000000000..8a32d9ac7e1
--- /dev/null
+++ b/sys/arch/sh/sh/interrupt.c
@@ -0,0 +1,752 @@
+/* $OpenBSD: interrupt.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: interrupt.c,v 1.18 2006/01/25 00:02:57 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+
+#include <uvm/uvm_extern.h> /* uvmexp.intrs */
+
+#include <net/netisr.h>
+
+#include <sh/clock.h>
+#include <sh/trap.h>
+#include <sh/intcreg.h>
+#include <sh/tmureg.h>
+#include <machine/intr.h>
+
+void intc_intr_priority(int, int);
+struct intc_intrhand *intc_alloc_ih(void);
+void intc_free_ih(struct intc_intrhand *);
+int intc_unknown_intr(void *);
+
+#ifdef SH4
+void intpri_intr_enable(int);
+void intpri_intr_disable(int);
+#endif
+
+void netintr(void);
+void tmu1_oneshot(void);
+int tmu1_intr(void *);
+void tmu2_oneshot(void);
+int tmu2_intr(void *);
+
+/*
+ * EVTCODE to intc_intrhand mapper.
+ * max #76 is SH4_INTEVT_TMU4 (0xb80)
+ */
+int8_t __intc_evtcode_to_ih[128];
+
+struct intc_intrhand __intc_intrhand[_INTR_N + 1] = {
+ /* Place holder interrupt handler for unregistered interrupt. */
+ [0] = { .ih_func = intc_unknown_intr, .ih_level = 0xf0 }
+};
+
+struct sh_soft_intr sh_soft_intrs[_IPL_NSOFT];
+struct sh_soft_intrhand *softnet_intrhand;
+
+/*
+ * SH INTC support.
+ */
+void
+intc_init(void)
+{
+
+ switch (cpu_product) {
+#ifdef SH3
+ case CPU_PRODUCT_7709:
+ case CPU_PRODUCT_7709A:
+ _reg_write_2(SH7709_IPRC, 0);
+ _reg_write_2(SH7709_IPRD, 0);
+ _reg_write_2(SH7709_IPRE, 0);
+ /* FALLTHROUGH */
+ case CPU_PRODUCT_7708:
+ case CPU_PRODUCT_7708S:
+ case CPU_PRODUCT_7708R:
+ _reg_write_2(SH3_IPRA, 0);
+ _reg_write_2(SH3_IPRB, 0);
+ break;
+#endif /* SH3 */
+
+#ifdef SH4
+ case CPU_PRODUCT_7751:
+ case CPU_PRODUCT_7751R:
+ _reg_write_4(SH4_INTPRI00, 0);
+ _reg_write_4(SH4_INTMSK00, INTMSK00_MASK_ALL);
+ /* FALLTHROUGH */
+ case CPU_PRODUCT_7750S:
+ case CPU_PRODUCT_7750R:
+ _reg_write_2(SH4_IPRD, 0);
+ /* FALLTHROUGH */
+ case CPU_PRODUCT_7750:
+ _reg_write_2(SH4_IPRA, 0);
+ _reg_write_2(SH4_IPRB, 0);
+ _reg_write_2(SH4_IPRC, 0);
+ break;
+#endif /* SH4 */
+ }
+}
+
+void *
+intc_intr_establish(int evtcode, int trigger, int level,
+ int (*ih_func)(void *), void *ih_arg, const char *name)
+{
+ struct intc_intrhand *ih;
+
+ KDASSERT(evtcode >= 0x200 && level > 0);
+
+ ih = intc_alloc_ih();
+ ih->ih_func = ih_func;
+ ih->ih_arg = ih_arg;
+ ih->ih_level = level << 4; /* convert to SR.IMASK format. */
+ ih->ih_evtcode = evtcode;
+
+ /* Map interrupt handler */
+ EVTCODE_TO_IH_INDEX(evtcode) = ih->ih_idx;
+
+ /* Priority */
+ intc_intr_priority(evtcode, level);
+
+ /* Sense select (SH7709, SH7709A only) XXX notyet */
+
+ return (ih);
+}
+
+void
+intc_intr_disestablish(void *arg)
+{
+ struct intc_intrhand *ih = arg;
+ int evtcode = ih->ih_evtcode;
+
+ /* Mask interrupt if IPR can manage it. if not, cascaded ICU will do */
+ intc_intr_priority(evtcode, 0);
+
+ /* Unmap interrupt handler */
+ EVTCODE_TO_IH_INDEX(evtcode) = 0;
+
+ intc_free_ih(ih);
+}
+
+void
+intc_intr_disable(int evtcode)
+{
+ int s;
+
+ s = _cpu_intr_suspend();
+ KASSERT(EVTCODE_TO_IH_INDEX(evtcode) != 0); /* there is a handler */
+ switch (evtcode) {
+ default:
+ intc_intr_priority(evtcode, 0);
+ break;
+
+#ifdef SH4
+ case SH4_INTEVT_PCISERR:
+ case SH4_INTEVT_PCIDMA3:
+ case SH4_INTEVT_PCIDMA2:
+ case SH4_INTEVT_PCIDMA1:
+ case SH4_INTEVT_PCIDMA0:
+ case SH4_INTEVT_PCIPWON:
+ case SH4_INTEVT_PCIPWDWN:
+ case SH4_INTEVT_PCIERR:
+ intpri_intr_disable(evtcode);
+ break;
+#endif
+ }
+ _cpu_intr_resume(s);
+}
+
+void
+intc_intr_enable(int evtcode)
+{
+ struct intc_intrhand *ih;
+ int s;
+
+ s = _cpu_intr_suspend();
+ KASSERT(EVTCODE_TO_IH_INDEX(evtcode) != 0); /* there is a handler */
+ switch (evtcode) {
+ default:
+ ih = EVTCODE_IH(evtcode);
+ /* ih_level is in the SR.IMASK format */
+ intc_intr_priority(evtcode, (ih->ih_level >> 4));
+ break;
+
+#ifdef SH4
+ case SH4_INTEVT_PCISERR:
+ case SH4_INTEVT_PCIDMA3:
+ case SH4_INTEVT_PCIDMA2:
+ case SH4_INTEVT_PCIDMA1:
+ case SH4_INTEVT_PCIDMA0:
+ case SH4_INTEVT_PCIPWON:
+ case SH4_INTEVT_PCIPWDWN:
+ case SH4_INTEVT_PCIERR:
+ intpri_intr_enable(evtcode);
+ break;
+#endif
+ }
+ _cpu_intr_resume(s);
+}
+
+
+/*
+ * int intc_intr_priority(int evtcode, int level)
+ * Setup interrupt priority register.
+ * SH7708, SH7708S, SH7708R, SH7750, SH7750S ... evtcode is INTEVT
+ * SH7709, SH7709A ... evtcode is INTEVT2
+ */
+void
+intc_intr_priority(int evtcode, int level)
+{
+ volatile uint16_t *iprreg;
+ int pos;
+ uint16_t r;
+
+#define __SH_IPR(_sh, _ipr, _pos) \
+ do { \
+ iprreg = (volatile uint16_t *)(SH ## _sh ## _IPR ## _ipr); \
+ pos = (_pos); \
+ } while (/*CONSTCOND*/0)
+
+#define SH3_IPR(_ipr, _pos) __SH_IPR(3, _ipr, _pos)
+#define SH4_IPR(_ipr, _pos) __SH_IPR(4, _ipr, _pos)
+#define SH7709_IPR(_ipr, _pos) __SH_IPR(7709, _ipr, _pos)
+
+#define SH_IPR(_ipr, _pos) \
+ do { \
+ if (CPU_IS_SH3) \
+ SH3_IPR(_ipr, _pos); \
+ else \
+ SH4_IPR(_ipr, _pos); \
+ } while (/*CONSTCOND*/0)
+
+ iprreg = 0;
+ pos = -1;
+
+ switch (evtcode) {
+ case SH_INTEVT_TMU0_TUNI0:
+ SH_IPR(A, 12);
+ break;
+ case SH_INTEVT_TMU1_TUNI1:
+ SH_IPR(A, 8);
+ break;
+ case SH_INTEVT_TMU2_TUNI2:
+ SH_IPR(A, 4);
+ break;
+ case SH_INTEVT_WDT_ITI:
+ SH_IPR(B, 12);
+ break;
+ case SH_INTEVT_SCI_ERI:
+ case SH_INTEVT_SCI_RXI:
+ case SH_INTEVT_SCI_TXI:
+ case SH_INTEVT_SCI_TEI:
+ SH_IPR(B, 4);
+ break;
+ }
+
+#ifdef SH3
+ if (CPU_IS_SH3) {
+ switch (evtcode) {
+ case SH7709_INTEVT2_IRQ3:
+ SH7709_IPR(C, 12);
+ break;
+ case SH7709_INTEVT2_IRQ2:
+ SH7709_IPR(C, 8);
+ break;
+ case SH7709_INTEVT2_IRQ1:
+ SH7709_IPR(C, 4);
+ break;
+ case SH7709_INTEVT2_IRQ0:
+ SH7709_IPR(C, 0);
+ break;
+ case SH7709_INTEVT2_PINT07:
+ SH7709_IPR(D, 12);
+ break;
+ case SH7709_INTEVT2_PINT8F:
+ SH7709_IPR(D, 8);
+ break;
+ case SH7709_INTEVT2_IRQ5:
+ SH7709_IPR(D, 4);
+ break;
+ case SH7709_INTEVT2_IRQ4:
+ SH7709_IPR(D, 0);
+ break;
+ case SH7709_INTEVT2_DEI0:
+ case SH7709_INTEVT2_DEI1:
+ case SH7709_INTEVT2_DEI2:
+ case SH7709_INTEVT2_DEI3:
+ SH7709_IPR(E, 12);
+ break;
+ case SH7709_INTEVT2_IRDA_ERI:
+ case SH7709_INTEVT2_IRDA_RXI:
+ case SH7709_INTEVT2_IRDA_BRI:
+ case SH7709_INTEVT2_IRDA_TXI:
+ SH7709_IPR(E, 8);
+ break;
+ case SH7709_INTEVT2_SCIF_ERI:
+ case SH7709_INTEVT2_SCIF_RXI:
+ case SH7709_INTEVT2_SCIF_BRI:
+ case SH7709_INTEVT2_SCIF_TXI:
+ SH7709_IPR(E, 4);
+ break;
+ case SH7709_INTEVT2_ADC:
+ SH7709_IPR(E, 0);
+ break;
+ }
+ }
+#endif /* SH3 */
+
+#ifdef SH4
+ if (CPU_IS_SH4) {
+ switch (evtcode) {
+ case SH4_INTEVT_SCIF_ERI:
+ case SH4_INTEVT_SCIF_RXI:
+ case SH4_INTEVT_SCIF_BRI:
+ case SH4_INTEVT_SCIF_TXI:
+ SH4_IPR(C, 4);
+ break;
+
+#if 0
+ case SH4_INTEVT_PCISERR:
+ case SH4_INTEVT_PCIDMA3:
+ case SH4_INTEVT_PCIDMA2:
+ case SH4_INTEVT_PCIDMA1:
+ case SH4_INTEVT_PCIDMA0:
+ case SH4_INTEVT_PCIPWON:
+ case SH4_INTEVT_PCIPWDWN:
+ case SH4_INTEVT_PCIERR:
+#endif
+ case SH4_INTEVT_TMU3:
+ case SH4_INTEVT_TMU4:
+ intpri_intr_priority(evtcode, level);
+ break;
+ }
+ }
+#endif /* SH4 */
+
+ /*
+ * XXX: This function gets called even for interrupts that
+ * don't have their priority defined by IPR registers.
+ */
+ if (pos < 0)
+ return;
+
+ r = _reg_read_2(iprreg);
+ r = (r & ~(0xf << (pos))) | (level << (pos));
+ _reg_write_2(iprreg, r);
+}
+
+/*
+ * Interrupt handler holder allocater.
+ */
+struct intc_intrhand *
+intc_alloc_ih(void)
+{
+ /* #0 is reserved for unregistered interrupt. */
+ struct intc_intrhand *ih = &__intc_intrhand[1];
+ int i;
+
+ for (i = 1; i <= _INTR_N; i++, ih++)
+ if (ih->ih_idx == 0) { /* no driver uses this. */
+ ih->ih_idx = i; /* register myself */
+ return (ih);
+ }
+
+ panic("increase _INTR_N greater than %d", _INTR_N);
+ return (NULL);
+}
+
+void
+intc_free_ih(struct intc_intrhand *ih)
+{
+ memset(ih, 0, sizeof(*ih));
+}
+
+/* Place-holder for debugging */
+int
+intc_unknown_intr(void *arg)
+{
+ printf("INTEVT=0x%x", _reg_read_4(SH_(INTEVT)));
+ if (cpu_product == CPU_PRODUCT_7709 || cpu_product == CPU_PRODUCT_7709A)
+ printf(" INTEVT2=0x%x", _reg_read_4(SH7709_INTEVT2));
+ printf("\n");
+
+ panic("unknown interrupt");
+ /* NOTREACHED */
+ return (0);
+}
+
+#ifdef SH4 /* SH7751 support */
+
+/*
+ * INTPRIxx
+ */
+void
+intpri_intr_priority(int evtcode, int level)
+{
+ volatile uint32_t *iprreg;
+ uint32_t r;
+ int pos;
+
+ if (!CPU_IS_SH4)
+ return;
+
+ switch (cpu_product) {
+ default:
+ return;
+
+ case CPU_PRODUCT_7751:
+ case CPU_PRODUCT_7751R:
+ break;
+ }
+
+ iprreg = (volatile uint32_t *)SH4_INTPRI00;
+ pos = -1;
+
+ switch (evtcode) {
+ case SH4_INTEVT_PCIDMA3:
+ case SH4_INTEVT_PCIDMA2:
+ case SH4_INTEVT_PCIDMA1:
+ case SH4_INTEVT_PCIDMA0:
+ case SH4_INTEVT_PCIPWDWN:
+ case SH4_INTEVT_PCIPWON:
+ case SH4_INTEVT_PCIERR:
+ pos = 0;
+ break;
+
+ case SH4_INTEVT_PCISERR:
+ pos = 4;
+ break;
+
+ case SH4_INTEVT_TMU3:
+ pos = 8;
+ break;
+
+ case SH4_INTEVT_TMU4:
+ pos = 12;
+ break;
+ }
+
+ if (pos < 0) {
+ return;
+ }
+
+ r = _reg_read_4(iprreg);
+ r = (r & ~(0xf << pos)) | (level << pos);
+ _reg_write_4(iprreg, r);
+}
+
+void
+intpri_intr_enable(int evtcode)
+{
+ volatile uint32_t *iprreg;
+ uint32_t bit;
+
+ if (!CPU_IS_SH4)
+ return;
+
+ switch (cpu_product) {
+ default:
+ return;
+
+ case CPU_PRODUCT_7751:
+ case CPU_PRODUCT_7751R:
+ break;
+ }
+
+ iprreg = (volatile uint32_t *)SH4_INTMSKCLR00;
+ bit = 0;
+
+ switch (evtcode) {
+ case SH4_INTEVT_PCISERR:
+ case SH4_INTEVT_PCIDMA3:
+ case SH4_INTEVT_PCIDMA2:
+ case SH4_INTEVT_PCIDMA1:
+ case SH4_INTEVT_PCIDMA0:
+ case SH4_INTEVT_PCIPWON:
+ case SH4_INTEVT_PCIPWDWN:
+ case SH4_INTEVT_PCIERR:
+ bit = (1 << ((evtcode - SH4_INTEVT_PCISERR) >> 5));
+ break;
+
+ case SH4_INTEVT_TMU3:
+ bit = INTREQ00_TUNI3;
+ break;
+
+ case SH4_INTEVT_TMU4:
+ bit = INTREQ00_TUNI4;
+ break;
+ }
+
+ if ((bit == 0) || (iprreg == NULL)) {
+ return;
+ }
+
+ _reg_write_4(iprreg, bit);
+}
+
+void
+intpri_intr_disable(int evtcode)
+{
+ volatile uint32_t *iprreg;
+ uint32_t bit;
+
+ if (!CPU_IS_SH4)
+ return;
+
+ switch (cpu_product) {
+ default:
+ return;
+
+ case CPU_PRODUCT_7751:
+ case CPU_PRODUCT_7751R:
+ break;
+ }
+
+ iprreg = (volatile uint32_t *)SH4_INTMSK00;
+ bit = 0;
+
+ switch (evtcode) {
+ case SH4_INTEVT_PCISERR:
+ case SH4_INTEVT_PCIDMA3:
+ case SH4_INTEVT_PCIDMA2:
+ case SH4_INTEVT_PCIDMA1:
+ case SH4_INTEVT_PCIDMA0:
+ case SH4_INTEVT_PCIPWON:
+ case SH4_INTEVT_PCIPWDWN:
+ case SH4_INTEVT_PCIERR:
+ bit = (1 << ((evtcode - SH4_INTEVT_PCISERR) >> 5));
+ break;
+
+ case SH4_INTEVT_TMU3:
+ bit = INTREQ00_TUNI3;
+ break;
+
+ case SH4_INTEVT_TMU4:
+ bit = INTREQ00_TUNI4;
+ break;
+ }
+
+ if ((bit == 0) || (iprreg == NULL)) {
+ return;
+ }
+
+ _reg_write_4(iprreg, bit);
+}
+#endif /* SH4 */
+
+/*
+ * Software interrupt support
+ */
+void
+softintr_init(void)
+{
+#if 0
+ static const char *softintr_names[] = IPL_SOFTNAMES;
+#endif
+ struct sh_soft_intr *asi;
+ int i;
+
+ for (i = 0; i < _IPL_NSOFT; i++) {
+ asi = &sh_soft_intrs[i];
+ TAILQ_INIT(&asi->softintr_q);
+
+ asi->softintr_ipl = IPL_SOFT + i;
+ simple_lock_init(&asi->softintr_slock);
+#if 0
+ evcnt_attach_dynamic(&asi->softintr_evcnt, EVCNT_TYPE_INTR,
+ NULL, "soft", softintr_names[i]);
+#endif
+ }
+
+ /* XXX Establish legacy soft interrupt handlers. */
+ softnet_intrhand = softintr_establish(IPL_SOFTNET,
+ (void (*)(void *))netintr, NULL);
+ KDASSERT(softnet_intrhand != NULL);
+
+ intc_intr_establish(SH_INTEVT_TMU1_TUNI1, IST_LEVEL, IPL_SOFT,
+ tmu1_intr, NULL, "tmu1");
+ intc_intr_establish(SH_INTEVT_TMU2_TUNI2, IST_LEVEL, IPL_SOFTNET,
+ tmu2_intr, NULL, "tmu2");
+}
+
+void
+softintr_dispatch(int ipl)
+{
+ struct sh_soft_intr *asi;
+ struct sh_soft_intrhand *sih;
+ int s;
+
+ s = _cpu_intr_suspend();
+
+ asi = &sh_soft_intrs[ipl - IPL_SOFT];
+
+ if (TAILQ_FIRST(&asi->softintr_q) != NULL)
+ asi->softintr_evcnt.ev_count++;
+
+ while ((sih = TAILQ_FIRST(&asi->softintr_q)) != NULL) {
+ TAILQ_REMOVE(&asi->softintr_q, sih, sih_q);
+ sih->sih_pending = 0;
+
+ uvmexp.softs++;
+
+ _cpu_intr_resume(s);
+ (*sih->sih_fn)(sih->sih_arg);
+ s = _cpu_intr_suspend();
+ }
+
+ _cpu_intr_resume(s);
+}
+
+void
+setsoft(int ipl)
+{
+ if (ipl < IPL_SOFTNET)
+ tmu1_oneshot();
+ else
+ tmu2_oneshot();
+}
+
+/* Register a software interrupt handler. */
+void *
+softintr_establish(int ipl, void (*func)(void *), void *arg)
+{
+ struct sh_soft_intr *asi;
+ struct sh_soft_intrhand *sih;
+ int s;
+
+ if (__predict_false(ipl >= (IPL_SOFT + _IPL_NSOFT) ||
+ ipl < IPL_SOFT))
+ panic("softintr_establish");
+
+ sih = malloc(sizeof(*sih), M_DEVBUF, M_NOWAIT);
+
+ s = _cpu_intr_suspend();
+ asi = &sh_soft_intrs[ipl - IPL_SOFT];
+ if (__predict_true(sih != NULL)) {
+ sih->sih_intrhead = asi;
+ sih->sih_fn = func;
+ sih->sih_arg = arg;
+ sih->sih_pending = 0;
+ }
+ _cpu_intr_resume(s);
+
+ return (sih);
+}
+
+/* Unregister a software interrupt handler. */
+void
+softintr_disestablish(void *arg)
+{
+ struct sh_soft_intrhand *sih = arg;
+ struct sh_soft_intr *asi = sih->sih_intrhead;
+ int s;
+
+ s = _cpu_intr_suspend();
+ if (sih->sih_pending) {
+ TAILQ_REMOVE(&asi->softintr_q, sih, sih_q);
+ sih->sih_pending = 0;
+ }
+ _cpu_intr_resume(s);
+
+ free(sih, M_DEVBUF);
+}
+
+/*
+ * Software (low priority) network interrupt. i.e. softnet().
+ */
+void
+netintr(void)
+{
+#define DONETISR(bit, fn) \
+ do { \
+ if (n & (1 << bit)) \
+ fn(); \
+ } while (/*CONSTCOND*/0)
+
+ int s, n;
+
+ s = splnet();
+ n = netisr;
+ netisr = 0;
+ splx(s);
+#include <net/netisr_dispatch.h>
+
+#undef DONETISR
+}
+
+/*
+ * Software interrupt is simulated with TMU one-shot timer.
+ */
+void
+tmu1_oneshot(void)
+{
+ _reg_bclr_1(SH_(TSTR), TSTR_STR1);
+ _reg_write_4(SH_(TCNT1), 0);
+ _reg_bset_1(SH_(TSTR), TSTR_STR1);
+}
+
+int
+tmu1_intr(void *arg)
+{
+ _reg_bclr_1(SH_(TSTR), TSTR_STR1);
+ _reg_bclr_2(SH_(TCR1), TCR_UNF);
+
+ softintr_dispatch(IPL_SOFTCLOCK);
+ softintr_dispatch(IPL_SOFT);
+
+ return (0);
+}
+
+void
+tmu2_oneshot(void)
+{
+ _reg_bclr_1(SH_(TSTR), TSTR_STR2);
+ _reg_write_4(SH_(TCNT2), 0);
+ _reg_bset_1(SH_(TSTR), TSTR_STR2);
+}
+
+int
+tmu2_intr(void *arg)
+{
+ _reg_bclr_1(SH_(TSTR), TSTR_STR2);
+ _reg_bclr_2(SH_(TCR2), TCR_UNF);
+
+ softintr_dispatch(IPL_SOFTSERIAL);
+ softintr_dispatch(IPL_SOFTNET);
+
+ return (0);
+}
diff --git a/sys/arch/sh/sh/locore_c.c b/sys/arch/sh/sh/locore_c.c
new file mode 100644
index 00000000000..f034e45846c
--- /dev/null
+++ b/sys/arch/sh/sh/locore_c.c
@@ -0,0 +1,286 @@
+/* $OpenBSD: locore_c.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: locore_c.c,v 1.13 2006/03/04 01:13:35 uwe Exp $ */
+
+/*-
+ * Copyright (c) 1996, 1997, 2002 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) 1982, 1987, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)Locore.c
+ */
+
+/*-
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * Charles M. Hannum. All rights reserved.
+ * Copyright (c) 1992 Terrence R. Lambert.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)Locore.c
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/user.h>
+#include <sys/sched.h>
+#include <sys/proc.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <sh/locore.h>
+#include <sh/cpu.h>
+#include <sh/pmap.h>
+#include <sh/mmu_sh3.h>
+#include <sh/mmu_sh4.h>
+
+void (*__sh_switch_resume)(struct proc *);
+struct proc *cpu_switch_search(struct proc *);
+struct proc *cpu_switch_prepare(struct proc *, struct proc *);
+void idle(void);
+int want_resched;
+
+#ifdef LOCKDEBUG
+#define SCHED_LOCK_IDLE() sched_lock_idle()
+#define SCHED_UNLOCK_IDLE() sched_unlock_idle()
+#else
+#define SCHED_LOCK_IDLE() do {} while (/* CONSTCOND */ 0)
+#define SCHED_UNLOCK_IDLE() do {} while (/* CONSTCOND */ 0)
+#endif
+
+
+/*
+ * Prepare context switch from oproc to nproc.
+ * This code is shared by cpu_switch and cpu_switchto.
+ */
+struct proc *
+cpu_switch_prepare(struct proc *oproc, struct proc *nproc)
+{
+ nproc->p_stat = SONPROC;
+
+ if (nproc != oproc) {
+ curpcb = nproc->p_md.md_pcb;
+ pmap_activate(nproc);
+ }
+
+ curproc = nproc;
+ return (nproc);
+}
+
+/*
+ * Find the highest priority proc and prepare to switching to it.
+ */
+struct proc *
+cpu_switch_search(struct proc *oproc)
+{
+ struct prochd *q;
+ struct proc *p;
+
+ curproc = NULL;
+
+ SCHED_LOCK_IDLE();
+ while (whichqs == 0) {
+ SCHED_UNLOCK_IDLE();
+ idle();
+ SCHED_LOCK_IDLE();
+ }
+
+ q = &qs[ffs(whichqs) - 1];
+ p = q->ph_link;
+ remrunqueue(p);
+ want_resched = 0;
+ SCHED_UNLOCK_IDLE();
+
+ return (cpu_switch_prepare(oproc, p));
+}
+
+/*
+ * void idle(void):
+ * When no processes are on the run queue, wait for something to come
+ * ready. Separated function for profiling.
+ */
+void
+idle()
+{
+ spl0();
+ uvm_pageidlezero();
+ __asm volatile("sleep");
+ splsched();
+}
+
+#ifndef P1_STACK
+#ifdef SH3
+/*
+ * void sh3_switch_setup(struct proc *p):
+ * prepare kernel stack PTE table. TLB miss handler check these.
+ */
+void
+sh3_switch_setup(struct proc *p)
+{
+ pt_entry_t *pte;
+ struct md_upte *md_upte = p->p_md.md_upte;
+ uint32_t vpn;
+ int i;
+
+ vpn = (uint32_t)p->p_addr;
+ vpn &= ~PGOFSET;
+ for (i = 0; i < UPAGES; i++, vpn += PAGE_SIZE, md_upte++) {
+ pte = __pmap_kpte_lookup(vpn);
+ KDASSERT(pte && *pte != 0);
+
+ md_upte->addr = vpn;
+ md_upte->data = (*pte & PG_HW_BITS) | PG_D | PG_V;
+ }
+}
+#endif /* SH3 */
+
+#ifdef SH4
+/*
+ * void sh4_switch_setup(struct proc *p):
+ * prepare kernel stack PTE table. sh4_switch_resume wired this PTE.
+ */
+void
+sh4_switch_setup(struct proc *p)
+{
+ pt_entry_t *pte;
+ struct md_upte *md_upte = p->p_md.md_upte;
+ uint32_t vpn;
+ int i, e;
+
+ vpn = (uint32_t)p->p_addr;
+ vpn &= ~PGOFSET;
+ e = SH4_UTLB_ENTRY - UPAGES;
+ for (i = 0; i < UPAGES; i++, e++, vpn += PAGE_SIZE) {
+ pte = __pmap_kpte_lookup(vpn);
+ KDASSERT(pte && *pte != 0);
+ /* Address array */
+ md_upte->addr = SH4_UTLB_AA | (e << SH4_UTLB_E_SHIFT);
+ md_upte->data = vpn | SH4_UTLB_AA_D | SH4_UTLB_AA_V;
+ md_upte++;
+ /* Data array */
+ md_upte->addr = SH4_UTLB_DA1 | (e << SH4_UTLB_E_SHIFT);
+ md_upte->data = (*pte & PG_HW_BITS) |
+ SH4_UTLB_DA1_D | SH4_UTLB_DA1_V;
+ md_upte++;
+ }
+}
+#endif /* SH4 */
+#endif /* !P1_STACK */
+
+/*
+ * copystr(caddr_t from, caddr_t to, size_t maxlen, size_t *lencopied);
+ * Copy a NUL-terminated string, at most maxlen characters long. Return the
+ * number of characters copied (including the NUL) in *lencopied. If the
+ * string is too long, return ENAMETOOLONG; else return 0.
+ */
+int
+copystr(const void *kfaddr, void *kdaddr, size_t maxlen, size_t *lencopied)
+{
+ const char *from = kfaddr;
+ char *to = kdaddr;
+ int i;
+
+ for (i = 0; maxlen-- > 0; i++) {
+ if ((*to++ = *from++) == '\0') {
+ if (lencopied)
+ *lencopied = i + 1;
+ return (0);
+ }
+ }
+
+ if (lencopied)
+ *lencopied = i;
+
+ return (ENAMETOOLONG);
+}
diff --git a/sys/arch/sh/sh/locore_subr.S b/sys/arch/sh/sh/locore_subr.S
new file mode 100644
index 00000000000..1f45dd721c7
--- /dev/null
+++ b/sys/arch/sh/sh/locore_subr.S
@@ -0,0 +1,866 @@
+/* $OpenBSD: locore_subr.S,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: locore_subr.S,v 1.28 2006/01/23 22:52:09 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ */
+
+#include "assym.h"
+
+#include <sys/syscall.h> /* SYS_sigreturn, SYS_exit */
+#include <sh/asm.h>
+#include <sh/locore.h>
+#include <sh/param.h> /* UPAGES */
+#include <sh/mmu_sh3.h>
+#include <sh/mmu_sh4.h>
+
+/*
+ * LINTSTUB: include <sys/types.h>
+ * LINTSTUB: include <sys/proc.h>
+ * LINTSTUB: include <sh/locore.h>
+ */
+
+ .text
+ .align 5 /* align cache line size (32B) */
+/*
+ * LINTSTUB: Func: int cpu_switch(struct proc *p, struct proc *XXX_IGNORED)
+ * Find a runnable proc and switch to it. Wait if necessary.
+ */
+ENTRY(cpu_switch)
+ /* Save current proc's context to switchframe */
+ mov.l .L_SF, r0
+ mov.l @(r0, r4), r1
+ add #SF_SIZE, r1
+ stc.l r7_bank,@-r1
+ stc.l sr, @-r1
+ stc.l r6_bank,@-r1
+ sts.l pr, @-r1
+ mov.l r8, @-r1
+ mov.l r9, @-r1
+ mov.l r10, @-r1
+ mov.l r11, @-r1
+ mov.l r12, @-r1
+ mov.l r13, @-r1
+ mov.l r14, @-r1
+ mov.l r15, @-r1
+
+.L_find_and_switch:
+ /* Search next proc. cpu_switch_search may or may not sleep. */
+ mov.l .L_cpu_switch_search, r0
+ jsr @r0
+ mov r4, r8 /* save old proc */
+
+ /* Skip context switch if same proc. */
+ cmp/eq r8, r0
+ bt/s 1f
+ mov r0, r4 /* new proc */
+
+.L_doswitch:
+ /* Setup kernel stack */
+ mov.l .L_SF, r0
+ mov.l @(r0, r4), r1 /* switch frame */
+ mov.l @(SF_R7_BANK, r1), r0 /* stack top */
+ mov.l @(SF_R6_BANK, r1), r2 /* current frame */
+ mov.l @(SF_R15, r1), r3 /* current stack */
+ /* During kernel stack switching, all interrupts are disabled. */
+ __EXCEPTION_BLOCK(r1, r5)
+ /* switch to new kernel stack */
+ ldc r0, r7_bank
+ ldc r2, r6_bank
+ mov r3, r15
+
+ /* Wire u-area */
+ MOV (switch_resume, r0)
+ jsr @r0
+ mov r4, r8 /* save new proc */
+ mov r8, r4
+ __EXCEPTION_UNBLOCK(r0, r1)
+ /* Now OK to use kernel stack. */
+
+ /* Return 1 indicating "we switched". */
+ bra 2f
+ mov #1, r2
+
+1: /* Return 0 indicating "didn't switch". */
+ mov #0, r2
+
+ /* Restore new proc's context from switchframe */
+ /* NOTE: r2 has return value! */
+2: mov.l .L_SF, r0
+ mov.l @(r0, r4), r1
+ add #4, r1 /* r15 already restored */
+ mov.l @r1+, r14
+ mov.l @r1+, r13
+ mov.l @r1+, r12
+ mov.l @r1+, r11
+ mov.l @r1+, r10
+ mov.l @r1+, r9
+ mov.l @r1+, r8
+ lds.l @r1+, pr
+ add #4, r1 /* r6_bank already restored */
+ ldc.l @r1+, sr
+
+ /* r2 has the return value; stuff it into r0 now. */
+ rts
+ mov r2, r0
+ .align 2
+.L_SF: .long (P_MD_PCB)
+.L_cpu_switch_search: .long _C_LABEL(cpu_switch_search)
+FUNC_SYMBOL(switch_resume)
+
+
+
+/*
+ * LINTSTUB: Func: void cpu_switchto(struct proc *current, struct proc *next)
+ * Switch to the specified next LWP.
+ */
+ENTRY(cpu_switchto)
+ /* Save current proc's context to switchframe. */
+ mov.l .L_SFp, r0
+ mov.l @(r0, r4), r1
+ add #SF_SIZE, r1
+ stc.l r7_bank,@-r1
+ stc.l sr, @-r1
+ stc.l r6_bank,@-r1
+ sts.l pr, @-r1
+ mov.l r8, @-r1
+ mov.l r9, @-r1
+ mov.l r10, @-r1
+ mov.l r11, @-r1
+ mov.l r12, @-r1
+ mov.l r13, @-r1
+ mov.l r14, @-r1
+ mov.l r15, @-r1
+
+ /*
+ * curproc = NULL;
+ * XXX Is this necessary? We know we won't go idle.
+ */
+ mov.l .L_curproc, r0
+ mov #0, r1
+ mov.l r1, @r0
+
+ /* old and new procs are already in r4, r5 */
+ mov.l .L_cpu_switch_prepare, r0
+ jsr @r0
+ nop
+
+ /*
+ * Put the incoming LWP in r4 and jump into the middle
+ * of cpu_switch(), and let it do the work to restore the
+ * incoming LWP's context.
+ */
+ bra .L_doswitch
+ mov r0, r4
+
+ .align 2
+.L_SFp: .long (P_MD_PCB)
+.L_curproc: .long _C_LABEL(curproc)
+.L_cpu_switch_prepare: .long _C_LABEL(cpu_switch_prepare)
+
+
+/*
+ * LINTSTUB: Func: void cpu_exit(struct proc *p)
+ * Just fall-through to the switch_exit below.
+ */
+ENTRY(cpu_exit)
+ mov.l .L_switch_exit_proc_exit2, r5 /* exit_func to call */
+ /* FALLTHROUGH */
+
+/*
+ * LINTSTUB: Func: void switch_exit(struct proc *p, void (*exit_func)(struct proc *))
+ * Called only from cpu_exit(p). Before we call exit_func to
+ * free proc's resources (including kernel stack) we need to
+ * switch to the proc0's kernel stack. Then we jump into the
+ * middle of cpu_switch to find and switch to a new proc.
+ */
+ALTENTRY(switch_exit)
+ mov.l .L_switch_exit_proc0_pcb, r1
+ mov.l .L_switch_exit_curpcb, r0
+ mov.l @r1, r1
+ mov.l r1, @r0 /* curpcb = proc0.p_md.md_pcb */
+
+ mov.l @(SF_R7_BANK, r1), r0 /* stack top */
+ mov.l @(SF_R6_BANK, r1), r2 /* current frame */
+ mov.l @(SF_R15, r1), r3 /* current stack */
+
+ /* switch to proc0's kernel stack */
+ __EXCEPTION_BLOCK(r1, r6)
+ ldc r0, r7_bank
+ ldc r2, r6_bank
+ mov r3, r15
+ __EXCEPTION_UNBLOCK(r0, r1)
+
+ /* safe to call (*exit_func)(p); now */
+ jsr @r5
+ nop /* proc is already in r4 */
+
+ /* proceed to cpu_switch */
+ bra .L_find_and_switch
+ mov #0, r4 /* no "previous" proc */
+
+ .align 2
+.L_switch_exit_proc_exit2:
+ .long _C_LABEL(proc_exit2)
+.L_switch_exit_proc0_pcb:
+ .long _C_LABEL(proc0) + P_MD_PCB
+.L_switch_exit_curpcb:
+ .long _C_LABEL(curpcb)
+
+
+#ifdef SH3
+/*
+ * LINTSTUB: Func: void sh3_switch_resume(struct proc *p)
+ * Set current u-area PTE array to curupte.
+ * No need to flush any entries. it is depended on u-area mapping is
+ * wired, and its mapping never cause modified/reference fault.
+ * u-area TLB fault is only covered by TLB miss exception.
+ * When the situation that "VPN match but not Valid" occur, SH3 jump to
+ * "generic exception" handler instead of TLB miss exception.
+ * But OpenBSD/sh code doesn't handle it. As the result, it causes
+ * hard reset. (never can access kernel stack).
+ */
+NENTRY(sh3_switch_resume)
+ mov.l .L_UPTE, r0
+ mov.l .L_curupte, r1
+ add r4, r0 /* p->p_md.md_upte */
+ rts
+ mov.l r0, @r1
+ .align 2
+.L_UPTE: .long P_MD_UPTE
+.L_curupte: .long _C_LABEL(curupte)
+ SET_ENTRY_SIZE(sh3_switch_resume)
+#endif /* SH3 */
+
+
+#ifdef SH4
+/*
+ * LINTSTUB: Func: void sh4_switch_resume(struct proc *p)
+ * Wire u-area. invalidate TLB entry for kernel stack to prevent
+ * TLB multiple hit.
+ */
+NENTRY(sh4_switch_resume)
+ mov.l .L_UPTE__sh4, r0
+ add r0, r4 /* p->p_md.md_upte */
+ mov #UPAGES,r3
+ mov #1, r2
+ mov.l @r4, r0 /* if (p->p_md.md_upte[0].addr == 0) return; */
+ tst r0, r0
+ bt 2f
+
+ /* Save old ASID and set ASID to zero */
+ xor r0, r0
+ mov.l .L_4_PTEH, r1
+ mov.l @r1, r7
+ mov.l r0, @r1
+
+ mov.l .L_VPN_MASK, r6
+ mov.l .L_4_UTLB_AA_A, r5
+
+ /* TLB address array must be accessed via P2. Setup jump address. */
+ mova 1f, r0
+ mov.l .L_P2BASE, r1
+ or r1, r0
+ jmp @r0 /* run P2 */
+ nop
+
+ /* Probe VPN match TLB entry and invalidate it. */
+ .align 2 /* mova target must be 4byte alignment */
+1: mov.l @(4, r4), r0
+ and r6, r0
+ mov.l r0, @r5 /* clear D, V */
+
+ /* Wire u-area TLB entry */
+ /* Address array */
+ mov.l @r4+, r0 /* addr */
+ mov.l @r4+, r1 /* data */
+ mov.l r1, @r0 /* *addr = data */
+
+ /* Data array */
+ mov.l @r4+, r0 /* addr */
+ mov.l @r4+, r1 /* data */
+ mov.l r1, @r0 /* *addr = data */
+ cmp/eq r2, r3
+ bf/s 1b
+ add #1, r2
+
+ /* restore ASID */
+ mov.l .L_4_PTEH, r0
+ mov.l r7, @r0
+ mova 2f, r0
+ jmp @r0 /* run P1 */
+ nop
+ .align 2
+2: rts /* mova target must be 4byte alignment */
+ nop
+ .align 2
+.L_UPTE__sh4: .long P_MD_UPTE
+.L_4_PTEH: .long SH4_PTEH
+.L_4_UTLB_AA_A: .long (SH4_UTLB_AA | SH4_UTLB_A)
+.L_4_ITLB_AA: .long SH4_ITLB_AA
+.L_VPN_MASK: .long 0xfffff000
+.L_P2BASE: .long 0xa0000000
+ SET_ENTRY_SIZE(sh4_switch_resume)
+#endif /* SH4 */
+
+
+/*
+ * LINTSTUB: Func: int _cpu_intr_raise(int s)
+ * raise SR.IMASK to 's'. if current SR.IMASK is greater equal 's',
+ * nothing to do. returns previous SR.IMASK.
+ */
+NENTRY(_cpu_intr_raise)
+ stc sr, r2
+ mov #0x78, r1
+ mov r2, r0
+ shll r1 /* r1 = 0xf0 */
+ and r1, r0 /* r0 = SR & 0xf0 */
+ cmp/ge r4, r0 /* r0 >= r4 ? T = 1 */
+ bt/s 1f
+ not r1, r1 /* r1 = 0xffffff0f */
+ and r1, r2 /* r2 = SR & ~0xf0 */
+ or r2, r4 /* r4 = (SR & ~0xf0) | s */
+ ldc r4, sr /* SR = r4 (don't move to delay slot) */
+1: rts
+ nop /* return (SR & 0xf0) */
+ SET_ENTRY_SIZE(_cpu_intr_raise)
+
+
+/*
+ * LINTSTUB: Func: int _cpu_intr_suspend(void)
+ * Mask all external interrupt. Returns previous SR.IMASK.
+ */
+NENTRY(_cpu_intr_suspend)
+ stc sr, r0 /* r0 = SR */
+ mov #0x78, r1
+ shll r1 /* r1 = 0x000000f0 */
+ mov r0, r2 /* r2 = SR */
+ or r1, r2 /* r2 |= 0x000000f0 */
+ ldc r2, sr /* SR = r2 */
+ rts
+ and r1, r0 /* r0 = SR & 0x000000f0 */
+ SET_ENTRY_SIZE(_cpu_intr_suspend)
+
+
+
+/*
+ * LINTSTUB: Func: int _cpu_intr_resume(int s)
+ * Set 's' to SR.IMASK. Returns previous SR.IMASK.
+ */
+NENTRY(_cpu_intr_resume)
+ stc sr, r0 /* r0 = SR */
+ mov #0x78, r2
+ shll r2 /* r2 = 0x000000f0 */
+ not r2, r1 /* r1 = 0xffffff0f */
+ and r0, r1 /* r1 = (SR & ~0xf0) */
+ or r1, r4 /* r4 = (SR & ~0xf0) | level */
+ ldc r4, sr /* SR = r0 (don't move to delay slot) */
+ rts
+ and r2, r0 /* return (SR & 0xf0) */
+ SET_ENTRY_SIZE(_cpu_intr_resume)
+
+
+/*
+ * LINTSTUB: Func: int _cpu_exception_suspend(void)
+ * Block exception (SR.BL). if external interrupt raise, pending interrupt.
+ * if exception occur, jump to 0xa0000000 (hard reset).
+ */
+NENTRY(_cpu_exception_suspend)
+ stc sr, r0 /* r0 = SR */
+ mov #0x10, r1
+ swap.b r1, r1
+ mov r0, r2 /* r2 = r0 */
+ swap.w r1, r1 /* r1 = 0x10000000 */
+ or r1, r2 /* r2 |= 0x10000000 */
+ ldc r2, sr /* SR = r2 */
+ rts
+ and r1, r0 /* r0 &= 0x10000000 */
+ SET_ENTRY_SIZE(_cpu_exception_suspend)
+
+
+/*
+ * LINTSTUB: Func: void _cpu_exception_resume(int s)
+ * restore 's' exception mask. (SR.BL)
+ */
+NENTRY(_cpu_exception_resume)
+ stc sr, r0 /* r0 = SR */
+ mov #0x10, r1
+ swap.b r1, r1
+ swap.w r1, r1
+ not r1, r1 /* r1 = ~0x10000000 */
+ and r1, r0 /* r0 &= ~0x10000000 */
+ or r4, r0 /* r0 |= old SR.BL */
+ ldc r0, sr /* SR = r0 (don't move to delay slot) */
+ rts
+ nop
+ SET_ENTRY_SIZE(_cpu_exception_resume)
+
+
+/*
+ * LINTSTUB: Func: void _cpu_spin(uint32_t count)
+ * Loop for 'count' * 10 cycles.
+ * [...]
+ * add IF ID EX MA WB
+ * nop IF ID EX MA WB
+ * cmp/pl IF ID EX MA WB - -
+ * nop IF ID EX MA - - WB
+ * bt IF ID EX . . MA WB
+ * nop IF ID - - EX MA WB
+ * nop IF - - ID EX MA WB
+ * nop - - - IF ID EX MA WB
+ * add IF ID EX MA WB
+ * nop IF ID EX MA WB
+ * cmp/pl IF ID EX MA WB - -
+ * nop IF ID EX MA - - WB
+ * bt IF ID EX . . MA
+ * [...]
+ */
+ .align 5 /* align cache line size (32B) */
+NENTRY(_cpu_spin)
+1: nop /* 1 */
+ nop /* 2 */
+ nop /* 3 */
+ add #-1, r4 /* 4 */
+ nop /* 5 */
+ cmp/pl r4 /* 6 */
+ nop /* 7 */
+ bt 1b /* 8, 9, 10 */
+ rts
+ nop
+ SET_ENTRY_SIZE(_cpu_spin)
+
+
+/*
+ * proc_trapmpoline:
+ * Call the service function with one argument specified by the r12 and r11
+ * respectively. set by cpu_fork().
+ */
+NENTRY(proc_trampoline)
+ jsr @r12
+ mov r11, r4
+ __EXCEPTION_RETURN
+ /* NOTREACHED */
+ SET_ENTRY_SIZE(proc_trampoline)
+
+
+/*
+ * LINTSTUB: Var: char sigcode[1]
+ * Signal trampoline.
+ *
+ * The kernel arranges for the signal handler to be invoked directly.
+ * This trampoline is used only to perform the return.
+ *
+ * On entry, the stack looks like this:
+ *
+ * sp-> sigcontext structure
+ */
+NENTRY(sigcode)
+ mov r15, r4 /* get pointer to sigcontext */
+ mov.l .L_SYS_sigreturn, r0
+ trapa #0x80 /* and call sigreturn() */
+ mov.l .L_SYS_exit, r0
+ trapa #0x80 /* exit if sigreturn fails */
+ /* NOTREACHED */
+
+ .align 2
+.L_SYS_sigreturn: .long SYS_sigreturn
+.L_SYS_exit: .long SYS_exit
+
+/* LINTSTUB: Var: char esigcode[1] */
+.globl _C_LABEL(esigcode)
+_C_LABEL(esigcode):
+ SET_ENTRY_SIZE(sigcode)
+
+/*
+ * LINTSTUB: Func: void savectx(struct pcb *pcb)
+ * save struct switchframe.
+ */
+ENTRY(savectx)
+ add #SF_SIZE, r4
+ stc.l r7_bank,@-r4
+ stc.l sr, @-r4
+ stc.l r6_bank,@-r4
+ sts.l pr, @-r4
+ mov.l r8, @-r4
+ mov.l r9, @-r4
+ mov.l r10, @-r4
+ mov.l r11, @-r4
+ mov.l r12, @-r4
+ mov.l r13, @-r4
+ mov.l r14, @-r4
+ rts
+ mov.l r15, @-r4
+ SET_ENTRY_SIZE(savectx)
+
+
+/*
+ * LINTSTUB: Func: int copyout(const void *ksrc, void *udst, size_t len)
+ * Copy len bytes into the user address space.
+ */
+ENTRY(copyout)
+ mov.l r14, @-r15
+ sts.l pr, @-r15
+ mov r15, r14
+
+ mov #EFAULT, r0 /* assume there was a problem */
+ mov r4, r3
+ mov r5, r2
+ mov r5, r4
+ add r6, r2
+ cmp/hs r5, r2 /* bomb if uaddr+len wraps */
+ bf 2f
+ mov.l .L_copyout_VM_MAXUSER_ADDRESS, r1
+ cmp/hi r1, r2 /* bomb if uaddr isn't in user space */
+ bt 2f
+
+ mov.l .L_copyout_curpcb, r1 /* set fault hander */
+ mov.l @r1, r2
+ mov.l .L_copyout_onfault, r1
+ mov.l r1, @(PCB_ONFAULT,r2)
+ mov.l .L_copyout_memcpy, r1
+ jsr @r1 /* memcpy(uaddr, kaddr, len) */
+ mov r3, r5
+
+ mov #0, r0
+1:
+ mov.l .L_copyout_curpcb, r1 /* clear fault handler */
+ mov.l @r1, r2
+ mov #0, r1
+ mov.l r1, @(PCB_ONFAULT,r2)
+2:
+ mov r14, r15
+ lds.l @r15+, pr
+ rts
+ mov.l @r15+, r14
+
+3:
+ bra 1b
+ mov #EFAULT, r0
+
+ .align 2
+.L_copyout_onfault:
+ .long 3b
+.L_copyout_VM_MAXUSER_ADDRESS:
+ .long VM_MAXUSER_ADDRESS
+.L_copyout_curpcb:
+ .long _C_LABEL(curpcb)
+.L_copyout_memcpy:
+ .long _C_LABEL(memcpy)
+ SET_ENTRY_SIZE(copyout)
+
+
+/*
+ * LINTSTUB: Func: int copyin(const void *usrc, void *kdst, size_t len)
+ * Copy len bytes from the user address space.
+ */
+ENTRY(copyin)
+ mov.l r14, @-r15
+ sts.l pr, @-r15
+ mov r15, r14
+
+ mov #EFAULT, r0 /* assume there was a problem */
+ mov r4, r3
+ mov r5, r4
+ mov r3, r2
+ add r6, r2
+ cmp/hs r3, r2 /* bomb if uaddr+len wraps */
+ bf 2f
+ mov.l .L_copyin_VM_MAXUSER_ADDRESS, r1
+ cmp/hi r1, r2 /* bomb if uaddr isn't in user space */
+ bt 2f
+
+ mov.l .L_copyin_curpcb, r1 /* set fault hander */
+ mov.l @r1, r2
+ mov.l .L_copyin_onfault, r1
+ mov.l r1, @(PCB_ONFAULT,r2)
+ mov.l .L_copyin_memcpy, r1
+ jsr @r1 /* memcpy(kaddr, uaddr, len) */
+ mov r3, r5
+
+ mov #0, r0
+1:
+ mov.l .L_copyin_curpcb, r1 /* clear fault hander */
+ mov.l @r1, r2
+ mov #0, r1
+ mov.l r1, @(PCB_ONFAULT,r2)
+2:
+ mov r14, r15
+ lds.l @r15+, pr
+ rts
+ mov.l @r15+, r14
+
+3:
+ bra 1b
+ mov #EFAULT, r0
+
+ .align 2
+.L_copyin_onfault:
+ .long 3b
+.L_copyin_VM_MAXUSER_ADDRESS:
+ .long VM_MAXUSER_ADDRESS
+.L_copyin_curpcb:
+ .long _C_LABEL(curpcb)
+.L_copyin_memcpy:
+ .long _C_LABEL(memcpy)
+ SET_ENTRY_SIZE(copyin)
+
+
+/*
+ * LINTSTUB: Func: int copyoutstr(const void *ksrc, void *udst, size_t maxlen, size_t *lencopied)
+ * Copy a NUL-terminated string, at most maxlen characters long,
+ * into the user address space. Return the number of characters
+ * copied (including the NUL) in *lencopied. If the string is
+ * too long, return ENAMETOOLONG; else return 0 or EFAULT.
+ */
+ENTRY(copyoutstr)
+ mov.l r8, @-r15
+
+ mov #EFAULT, r3 /* assume there was a problem */
+ mov r4, r8
+ mov.l .L_copyoutstr_curpcb, r1 /* set fault handler */
+ mov.l @r1, r2
+ mov.l .L_copyoutstr_onfault, r1
+ mov.l r1, @(PCB_ONFAULT,r2)
+ mov.l .L_copyoutstr_VM_MAXUSER_ADDRESS, r1
+ mov r1, r0
+ sub r5, r0
+ cmp/hi r6, r0 /* don't beyond user space */
+ bf 2f
+ bra 2f
+ mov r6, r0
+
+ .align 2
+1:
+ mov.b @r4+, r1 /* copy str */
+ mov.b r1, @r5
+ extu.b r1, r1
+ add #1, r5
+ tst r1, r1
+ bf 2f
+ bra 3f
+ mov #0, r3
+ .align 2
+2:
+ add #-1, r0
+ cmp/eq #-1, r0
+ bf 1b
+ mov.l .L_copyoutstr_VM_MAXUSER_ADDRESS, r1
+ cmp/hs r1, r5
+ bt 3f
+ mov #ENAMETOOLONG, r3
+
+3:
+ tst r7, r7 /* set lencopied if needed */
+ bt 4f
+ mov r4, r1
+ sub r8, r1
+ mov.l r1, @r7
+4:
+ mov.l .L_copyoutstr_curpcb, r1 /* clear fault handler */
+ mov.l @r1, r2
+ mov #0, r1
+ mov.l r1, @(PCB_ONFAULT,r2)
+
+ mov r3, r0
+ rts
+ mov.l @r15+, r8
+
+5:
+ bra 4b
+ mov #EFAULT, r3
+
+ .align 2
+.L_copyoutstr_onfault:
+ .long 5b
+.L_copyoutstr_VM_MAXUSER_ADDRESS:
+ .long VM_MAXUSER_ADDRESS
+.L_copyoutstr_curpcb:
+ .long _C_LABEL(curpcb)
+ SET_ENTRY_SIZE(copyoutstr)
+
+
+/*
+ * LINTSTUB: Func: int copyinstr(const void *src, void *dst, size_t maxlen, size_t *lencopied)
+ * Copy a NUL-terminated string, at most maxlen characters long,
+ * from the user address space. Return the number of characters
+ * copied (including the NUL) in *lencopied. If the string is
+ * too long, return ENAMETOOLONG; else return 0 or EFAULT.
+ */
+ENTRY(copyinstr)
+ mov.l r8, @-r15
+ mov #EFAULT, r3 /* assume there was a problem */
+ mov r4, r8
+ mov.l .L_copyinstr_curpcb, r1 /* set fault handler */
+ mov.l @r1, r2
+ mov.l .L_copyinstr_onfault, r1
+ mov.l r1, @(PCB_ONFAULT,r2)
+
+ mov.l .L_copyinstr_VM_MAXUSER_ADDRESS, r1
+ mov r1, r0
+ sub r5, r0
+ cmp/hi r6, r0 /* don't beyond user space */
+ bf 2f
+ bra 2f
+ mov r6, r0
+
+ .align 2
+1:
+ mov.b @r4+, r1 /* copy str */
+ mov.b r1, @r5
+ extu.b r1, r1
+ add #1, r5
+ tst r1, r1
+ bf 2f
+ bra 3f
+ mov #0, r3
+ .align 2
+2:
+ add #-1, r0
+ cmp/eq #-1, r0
+ bf 1b
+ mov.l .L_copyinstr_VM_MAXUSER_ADDRESS, r1
+ cmp/hs r1, r5
+ bt 3f
+ mov #ENAMETOOLONG, r3
+
+3:
+ tst r7, r7 /* set lencopied if needed */
+ bt 4f
+ mov r4, r1
+ sub r8, r1
+ mov.l r1, @r7
+4:
+ mov.l .L_copyinstr_curpcb, r1 /* clear fault handler */
+ mov.l @r1, r2
+ mov #0, r1
+ mov.l r1, @(PCB_ONFAULT,r2)
+
+ mov r3, r0
+ rts
+ mov.l @r15+, r8
+
+5:
+ bra 4b
+ mov #EFAULT, r3
+
+ .align 2
+.L_copyinstr_onfault:
+ .long 5b
+.L_copyinstr_VM_MAXUSER_ADDRESS:
+ .long VM_MAXUSER_ADDRESS
+.L_copyinstr_curpcb:
+ .long _C_LABEL(curpcb)
+ SET_ENTRY_SIZE(copyinstr)
+
+/*
+ * LINTSTUB: Func: int kcopy(const void *src, void *dst, size_t len)
+ */
+ENTRY(kcopy)
+ mov.l r8, @-r15
+ mov.l r14, @-r15
+ sts.l pr, @-r15
+ mov r15, r14
+
+ mov r4, r3
+ mov.l .L_kcopy_curpcb, r1
+ mov.l @r1, r2
+ mov.l @(PCB_ONFAULT,r2) ,r8 /* save old fault handler */
+ mov.l .L_kcopy_onfault, r1
+ mov.l r1, @(PCB_ONFAULT,r2) /* set fault handler */
+ mov.l .L_kcopy_memcpy, r1
+ mov r5, r4
+ jsr @r1 /* memcpy(dst, src, len) */
+ mov r3, r5
+ mov #0, r0
+1:
+ mov.l .L_kcopy_curpcb, r1 /* restore fault handler */
+ mov.l @r1, r2
+ mov.l r8, @(PCB_ONFAULT,r2)
+
+ mov r14, r15
+ lds.l @r15+, pr
+ mov.l @r15+, r14
+ rts
+ mov.l @r15+, r8
+
+2:
+ bra 1b
+ mov #EFAULT, r0
+
+ .align 2
+.L_kcopy_onfault:
+ .long 2b
+.L_kcopy_curpcb:
+ .long _C_LABEL(curpcb)
+.L_kcopy_memcpy:
+ .long _C_LABEL(memcpy)
+ SET_ENTRY_SIZE(kcopy)
+
+
+#if defined(DDB)
+
+/*
+ * LINTSTUB: Func: int setjmp(label_t *jmpbuf)
+ */
+ENTRY(setjmp)
+ add #4*9, r4
+ mov.l r8, @-r4
+ mov.l r9, @-r4
+ mov.l r10, @-r4
+ mov.l r11, @-r4
+ mov.l r12, @-r4
+ mov.l r13, @-r4
+ mov.l r14, @-r4
+ mov.l r15, @-r4
+ sts.l pr, @-r4
+ rts
+ xor r0, r0
+ SET_ENTRY_SIZE(setjmp)
+
+/*
+ * LINTSTUB: Func: void longjmp(label_t *jmpbuf)
+ */
+ENTRY(longjmp)
+ lds.l @r4+, pr
+ mov.l @r4+, r15
+ mov.l @r4+, r14
+ mov.l @r4+, r13
+ mov.l @r4+, r12
+ mov.l @r4+, r11
+ mov.l @r4+, r10
+ mov.l @r4+, r9
+ mov.l @r4+, r8
+ rts
+ mov #1, r0 /* return 1 from setjmp */
+ SET_ENTRY_SIZE(longjmp)
+
+#endif /* DDB */
diff --git a/sys/arch/sh/sh/mem.c b/sys/arch/sh/sh/mem.c
new file mode 100644
index 00000000000..26055857312
--- /dev/null
+++ b/sys/arch/sh/sh/mem.c
@@ -0,0 +1,260 @@
+/* $OpenBSD: mem.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: mem.c,v 1.21 2006/07/23 22:06:07 ad Exp $ */
+
+/*
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)mem.c 8.3 (Berkeley) 1/12/94
+ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)mem.c 8.3 (Berkeley) 1/12/94
+ */
+
+/*
+ * Memory special file
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/conf.h>
+
+#include <uvm/uvm_extern.h>
+
+caddr_t zeropage;
+boolean_t __mm_mem_addr(paddr_t);
+
+#define mmread mmrw
+#define mmwrite mmrw
+cdev_decl(mm);
+
+#define DEV_MEM 0
+#define DEV_KMEM 1
+#define DEV_NULL 2
+#define DEV_ZERO 12
+
+/* ARGSUSED */
+int
+mmopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ switch (minor(dev)) {
+ case DEV_MEM:
+ case DEV_KMEM:
+ case DEV_NULL:
+ case DEV_ZERO:
+ break;
+ default:
+ return (ENXIO);
+ }
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+mmclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+mmrw(dev_t dev, struct uio *uio, int flags)
+{
+ struct iovec *iov;
+ vaddr_t v, o;
+ int c;
+ int error = 0;
+
+ while (uio->uio_resid > 0 && !error) {
+ iov = uio->uio_iov;
+ if (iov->iov_len == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ if (uio->uio_iovcnt < 0)
+ panic("mmrw");
+ continue;
+ }
+
+ v = uio->uio_offset;
+
+ switch (minor(dev)) {
+kmemphys:
+ case DEV_MEM:
+ /* Physical address */
+ if (__mm_mem_addr(v)) {
+ o = v & PGOFSET;
+ c = min(uio->uio_resid, (int)(PAGE_SIZE - o));
+ error = uiomove((caddr_t)SH3_PHYS_TO_P1SEG(v),
+ c, uio);
+ } else {
+ return (EFAULT);
+ }
+ break;
+
+ case DEV_KMEM:
+ /* P0 */
+ if (v < SH3_P1SEG_BASE)
+ return (EFAULT);
+ /* P1 */
+ if (v < SH3_P2SEG_BASE) {
+ v = SH3_P1SEG_TO_PHYS(v);
+ goto kmemphys;
+ }
+ /* P2 */
+ if (v < SH3_P3SEG_BASE)
+ return (EFAULT);
+ /* P3 */
+ c = min(iov->iov_len, MAXPHYS);
+ if (!uvm_kernacc((void *)v, c,
+ uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
+ return (EFAULT);
+ error = uiomove((caddr_t)v, c, uio);
+ break;
+
+ case DEV_NULL:
+ if (uio->uio_rw == UIO_WRITE)
+ uio->uio_resid = 0;
+ return (0);
+
+ case DEV_ZERO:
+ if (uio->uio_rw == UIO_WRITE) {
+ uio->uio_resid = 0;
+ return (0);
+ }
+ if (zeropage == NULL) {
+ zeropage = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
+ memset(zeropage, 0, PAGE_SIZE);
+ }
+ c = min(iov->iov_len, PAGE_SIZE);
+ error = uiomove(zeropage, c, uio);
+ break;
+
+ default:
+ return (ENXIO);
+ }
+ }
+
+ return (error);
+}
+
+/*ARGSUSED*/
+paddr_t
+mmmmap(dev_t dev, off_t off, int prot)
+{
+ struct proc *p = curproc;
+
+ if (minor(dev) != DEV_MEM)
+ return (-1);
+
+ if (__mm_mem_addr((paddr_t)off) == FALSE && suser(p, 0) != 0)
+ return (-1);
+ return (atop((paddr_t)off));
+}
+
+/*ARGSUSED*/
+int
+mmioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ return (EOPNOTSUPP);
+}
+
+/*
+ * boolean_t __mm_mem_addr(paddr_t pa):
+ * Check specified physical address is in physical memory, with the
+ * kernel image off-limits.
+ */
+boolean_t
+__mm_mem_addr(paddr_t pa)
+{
+ extern vaddr_t kernend; /* from machdep.c */
+ struct vm_physseg *seg;
+ unsigned int segno;
+
+ for (segno = 0, seg = vm_physmem; segno < vm_nphysseg; segno++, seg++) {
+ if (pa < seg->start || pa >= seg->end)
+ continue;
+
+ /*
+ * This assumes the kernel image occupies the beginning of a
+ * memory segment.
+ */
+ if (kernend >= seg->start && kernend < seg->end) {
+ if (pa < kernend)
+ return (FALSE);
+ }
+
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
diff --git a/sys/arch/sh/sh/mmu.c b/sys/arch/sh/sh/mmu.c
new file mode 100644
index 00000000000..cd093d9b73c
--- /dev/null
+++ b/sys/arch/sh/sh/mmu.c
@@ -0,0 +1,110 @@
+/* $OpenBSD: mmu.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: mmu.c,v 1.15 2006/02/12 02:30:55 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sh/mmu.h>
+#include <sh/mmu_sh3.h>
+#include <sh/mmu_sh4.h>
+
+#if defined(SH3) && defined(SH4)
+void (*__sh_mmu_start)(void);
+void (*__sh_tlb_invalidate_addr)(int, vaddr_t);
+void (*__sh_tlb_invalidate_asid)(int);
+void (*__sh_tlb_invalidate_all)(void);
+void (*__sh_tlb_update)(int, vaddr_t, uint32_t);
+#endif /* SH3 && SH4 */
+
+void
+sh_mmu_init(void)
+{
+ /*
+ * Assign function hooks but only if both SH3 and SH4 are defined.
+ * They are called directly otherwise. See <sh3/mmu.h>.
+ */
+#if defined(SH3) && defined(SH4)
+ if (CPU_IS_SH3) {
+ __sh_mmu_start = sh3_mmu_start;
+ __sh_tlb_invalidate_addr = sh3_tlb_invalidate_addr;
+ __sh_tlb_invalidate_asid = sh3_tlb_invalidate_asid;
+ __sh_tlb_invalidate_all = sh3_tlb_invalidate_all;
+ __sh_tlb_update = sh3_tlb_update;
+ }
+ else if (CPU_IS_SH4) {
+ __sh_mmu_start = sh4_mmu_start;
+ __sh_tlb_invalidate_addr = sh4_tlb_invalidate_addr;
+ __sh_tlb_invalidate_asid = sh4_tlb_invalidate_asid;
+ __sh_tlb_invalidate_all = sh4_tlb_invalidate_all;
+ __sh_tlb_update = sh4_tlb_update;
+ }
+#endif /* SH3 && SH4 */
+}
+
+void
+sh_mmu_information(void)
+{
+ uint32_t r;
+#ifdef SH3
+ if (CPU_IS_SH3) {
+ printf("cpu0: 4-way set-associative 128 TLB entries\n");
+ r = _reg_read_4(SH3_MMUCR);
+ printf("cpu0: %s mode, %s virtual storage mode\n",
+ r & SH3_MMUCR_IX ? "ASID+VPN" : "VPN",
+ r & SH3_MMUCR_SV ? "single" : "multiple");
+ }
+#endif
+#ifdef SH4
+ if (CPU_IS_SH4) {
+ printf("cpu0: full-associative 4 ITLB, 64 UTLB entries\n");
+ r = _reg_read_4(SH4_MMUCR);
+ printf("cpu0: %s virtual storage mode, SQ access: kernel%s, ",
+ r & SH3_MMUCR_SV ? "single" : "multiple",
+ r & SH4_MMUCR_SQMD ? "" : "/user");
+ printf("wired %d\n",
+ (r & SH4_MMUCR_URB_MASK) >> SH4_MMUCR_URB_SHIFT);
+ }
+#endif
+}
+
+void
+sh_tlb_set_asid(int asid)
+{
+ _reg_write_4(SH_(PTEH), asid);
+}
diff --git a/sys/arch/sh/sh/mmu_sh3.c b/sys/arch/sh/sh/mmu_sh3.c
new file mode 100644
index 00000000000..c5b9f814a8b
--- /dev/null
+++ b/sys/arch/sh/sh/mmu_sh3.c
@@ -0,0 +1,136 @@
+/* $OpenBSD: mmu_sh3.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: mmu_sh3.c,v 1.11 2006/03/04 01:13:35 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sh/pte.h> /* OpenBSD/sh specific PTE */
+#include <sh/mmu.h>
+#include <sh/mmu_sh3.h>
+
+void
+sh3_mmu_start()
+{
+ /* Zero clear all TLB entry */
+ sh3_tlb_invalidate_all();
+
+ /* Set current ASID to 0 */
+ sh_tlb_set_asid(0);
+
+ _reg_write_4(SH3_MMUCR, SH3_MMUCR_AT | SH3_MMUCR_TF);
+}
+
+void
+sh3_tlb_invalidate_addr(int asid, vaddr_t va)
+{
+ uint32_t a, d;
+ int w;
+
+ d = (va & SH3_MMUAA_D_VPN_MASK_4K) | asid; /* 4K page */
+ va = va & SH3_MMU_VPN_MASK; /* [16:12] entry index */
+
+ /* Probe entry and invalidate it. */
+ for (w = 0; w < SH3_MMU_WAY; w++) {
+ a = va | (w << SH3_MMU_WAY_SHIFT); /* way [9:8] */
+ if ((_reg_read_4(SH3_MMUAA | a) &
+ (SH3_MMUAA_D_VPN_MASK_4K | SH3_MMUAA_D_ASID_MASK)) == d) {
+ _reg_write_4(SH3_MMUAA | a, 0);
+ break;
+ }
+ }
+}
+
+void
+sh3_tlb_invalidate_asid(int asid)
+{
+ uint32_t aw, a;
+ int e, w;
+
+ /* Invalidate entry attribute to ASID */
+ for (w = 0; w < SH3_MMU_WAY; w++) {
+ aw = (w << SH3_MMU_WAY_SHIFT);
+ for (e = 0; e < SH3_MMU_ENTRY; e++) {
+ a = aw | (e << SH3_MMU_VPN_SHIFT);
+ if ((_reg_read_4(SH3_MMUAA | a) &
+ SH3_MMUAA_D_ASID_MASK) == asid) {
+ _reg_write_4(SH3_MMUAA | a, 0);
+ }
+ }
+ }
+}
+
+void
+sh3_tlb_invalidate_all()
+{
+ uint32_t aw, a;
+ int e, w;
+
+ /* Zero clear all TLB entry to avoid unexpected VPN match. */
+ for (w = 0; w < SH3_MMU_WAY; w++) {
+ aw = (w << SH3_MMU_WAY_SHIFT);
+ for (e = 0; e < SH3_MMU_ENTRY; e++) {
+ a = aw | (e << SH3_MMU_VPN_SHIFT);
+ _reg_write_4(SH3_MMUAA | a, 0);
+ _reg_write_4(SH3_MMUDA | a, 0);
+ }
+ }
+}
+
+void
+sh3_tlb_update(int asid, vaddr_t va, uint32_t pte)
+{
+ uint32_t oasid;
+
+ KDASSERT(asid < 0x100 && (pte & ~PGOFSET) != 0 && va != 0);
+
+ /* Save old ASID */
+ oasid = _reg_read_4(SH3_PTEH) & SH3_PTEH_ASID_MASK;
+
+ /* Invalidate old entry (if any) */
+ sh3_tlb_invalidate_addr(asid, va);
+
+ /* Load new entry */
+ _reg_write_4(SH3_PTEH, (va & ~PGOFSET) | asid);
+ _reg_write_4(SH3_PTEL, pte & PG_HW_BITS);
+ __asm volatile("ldtlb");
+
+ /* Restore old ASID */
+ if (asid != oasid)
+ _reg_write_4(SH3_PTEH, oasid);
+}
diff --git a/sys/arch/sh/sh/mmu_sh4.c b/sys/arch/sh/sh/mmu_sh4.c
new file mode 100644
index 00000000000..873534ff9d5
--- /dev/null
+++ b/sys/arch/sh/sh/mmu_sh4.c
@@ -0,0 +1,184 @@
+/* $OpenBSD: mmu_sh4.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: mmu_sh4.c,v 1.11 2006/03/04 01:13:35 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sh/pte.h> /* OpenBSD/sh specific PTE */
+#include <sh/mmu.h>
+#include <sh/mmu_sh4.h>
+
+#define SH4_MMU_HAZARD __asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;")
+
+static inline void __sh4_itlb_invalidate_all(void);
+
+static inline void
+__sh4_itlb_invalidate_all()
+{
+ _reg_write_4(SH4_ITLB_AA, 0);
+ _reg_write_4(SH4_ITLB_AA | (1 << SH4_ITLB_E_SHIFT), 0);
+ _reg_write_4(SH4_ITLB_AA | (2 << SH4_ITLB_E_SHIFT), 0);
+ _reg_write_4(SH4_ITLB_AA | (3 << SH4_ITLB_E_SHIFT), 0);
+}
+
+void
+sh4_mmu_start()
+{
+ /* Zero clear all TLB entry */
+ _reg_write_4(SH4_MMUCR, 0); /* zero wired entry */
+ sh_tlb_invalidate_all();
+
+ /* Set current ASID to 0 */
+ sh_tlb_set_asid(0);
+
+ /*
+ * User can't access store queue
+ * make wired entry for u-area.
+ */
+ _reg_write_4(SH4_MMUCR, SH4_MMUCR_AT | SH4_MMUCR_TI | SH4_MMUCR_SQMD |
+ (SH4_UTLB_ENTRY - UPAGES) << SH4_MMUCR_URB_SHIFT);
+
+ SH4_MMU_HAZARD;
+}
+
+void
+sh4_tlb_invalidate_addr(int asid, vaddr_t va)
+{
+ uint32_t pteh;
+ int s;
+
+ va &= SH4_PTEH_VPN_MASK;
+ s = _cpu_exception_suspend();
+
+ /* Save current ASID */
+ pteh = _reg_read_4(SH4_PTEH);
+ /* Set ASID for associative write */
+ _reg_write_4(SH4_PTEH, asid);
+
+ /* Associative write(UTLB/ITLB). not required ITLB invalidate. */
+ RUN_P2;
+ _reg_write_4(SH4_UTLB_AA | SH4_UTLB_A, va); /* Clear D, V */
+ RUN_P1;
+ /* Restore ASID */
+ _reg_write_4(SH4_PTEH, pteh);
+
+ _cpu_exception_resume(s);
+}
+
+void
+sh4_tlb_invalidate_asid(int asid)
+{
+ uint32_t a;
+ int e, s;
+
+ s = _cpu_exception_suspend();
+ /* Invalidate entry attribute to ASID */
+ RUN_P2;
+ for (e = 0; e < SH4_UTLB_ENTRY; e++) {
+ a = SH4_UTLB_AA | (e << SH4_UTLB_E_SHIFT);
+ if ((_reg_read_4(a) & SH4_UTLB_AA_ASID_MASK) == asid)
+ _reg_write_4(a, 0);
+ }
+
+ __sh4_itlb_invalidate_all();
+ RUN_P1;
+ _cpu_exception_resume(s);
+}
+
+void
+sh4_tlb_invalidate_all()
+{
+ uint32_t a;
+ int e, eend, s;
+
+ s = _cpu_exception_suspend();
+ /* If non-wired entry limit is zero, clear all entry. */
+ a = _reg_read_4(SH4_MMUCR) & SH4_MMUCR_URB_MASK;
+ eend = a ? (a >> SH4_MMUCR_URB_SHIFT) : SH4_UTLB_ENTRY;
+
+ RUN_P2;
+ for (e = 0; e < eend; e++) {
+ a = SH4_UTLB_AA | (e << SH4_UTLB_E_SHIFT);
+ _reg_write_4(a, 0);
+ a = SH4_UTLB_DA1 | (e << SH4_UTLB_E_SHIFT);
+ _reg_write_4(a, 0);
+ }
+ __sh4_itlb_invalidate_all();
+ _reg_write_4(SH4_ITLB_DA1, 0);
+ _reg_write_4(SH4_ITLB_DA1 | (1 << SH4_ITLB_E_SHIFT), 0);
+ _reg_write_4(SH4_ITLB_DA1 | (2 << SH4_ITLB_E_SHIFT), 0);
+ _reg_write_4(SH4_ITLB_DA1 | (3 << SH4_ITLB_E_SHIFT), 0);
+ RUN_P1;
+ _cpu_exception_resume(s);
+}
+
+void
+sh4_tlb_update(int asid, vaddr_t va, uint32_t pte)
+{
+ uint32_t oasid;
+ uint32_t ptel;
+ int s;
+
+ KDASSERT(asid < 0x100 && (pte & ~PGOFSET) != 0 && va != 0);
+
+ s = _cpu_exception_suspend();
+ /* Save old ASID */
+ oasid = _reg_read_4(SH4_PTEH) & SH4_PTEH_ASID_MASK;
+
+ /* Invalidate old entry (if any) */
+ sh4_tlb_invalidate_addr(asid, va);
+
+ _reg_write_4(SH4_PTEH, asid);
+ /* Load new entry */
+ _reg_write_4(SH4_PTEH, (va & ~PGOFSET) | asid);
+ ptel = pte & PG_HW_BITS;
+ if (pte & _PG_PCMCIA) {
+ _reg_write_4(SH4_PTEA,
+ (pte >> _PG_PCMCIA_SHIFT) & SH4_PTEA_SA_MASK);
+ } else {
+ _reg_write_4(SH4_PTEA, 0);
+ }
+ _reg_write_4(SH4_PTEL, ptel);
+ __asm volatile("ldtlb; nop");
+
+ /* Restore old ASID */
+ if (asid != oasid)
+ _reg_write_4(SH4_PTEH, oasid);
+ _cpu_exception_resume(s);
+}
diff --git a/sys/arch/sh/sh/pmap.c b/sys/arch/sh/sh/pmap.c
new file mode 100644
index 00000000000..3f432895bb7
--- /dev/null
+++ b/sys/arch/sh/sh/pmap.c
@@ -0,0 +1,1029 @@
+/* $OpenBSD: pmap.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: pmap.c,v 1.55 2006/08/07 23:19:36 tsutsui Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/pool.h>
+#include <sys/msgbuf.h>
+
+#include <uvm/uvm.h>
+
+#include <sh/mmu.h>
+#include <sh/cache.h>
+
+#ifdef DEBUG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+#define __PMAP_PTP_SHIFT 22
+#define __PMAP_PTP_TRUNC(va) \
+ (((va) + (1 << __PMAP_PTP_SHIFT) - 1) & ~((1 << __PMAP_PTP_SHIFT) - 1))
+#define __PMAP_PTP_PG_N (PAGE_SIZE / sizeof(pt_entry_t))
+#define __PMAP_PTP_INDEX(va) (((va) >> __PMAP_PTP_SHIFT) & (__PMAP_PTP_N - 1))
+#define __PMAP_PTP_OFSET(va) ((va >> PGSHIFT) & (__PMAP_PTP_PG_N - 1))
+
+struct pmap __pmap_kernel;
+STATIC vaddr_t __pmap_kve; /* VA of last kernel virtual */
+paddr_t avail_start; /* PA of first available physical page */
+paddr_t avail_end; /* PA of last available physical page */
+
+/* pmap pool */
+STATIC struct pool __pmap_pmap_pool;
+
+/* pv_entry ops. */
+struct pv_entry {
+ struct pmap *pv_pmap;
+ vaddr_t pv_va;
+ SLIST_ENTRY(pv_entry) pv_link;
+};
+#define __pmap_pv_alloc() pool_get(&__pmap_pv_pool, PR_NOWAIT)
+#define __pmap_pv_free(pv) pool_put(&__pmap_pv_pool, (pv))
+STATIC void __pmap_pv_enter(pmap_t, struct vm_page *, vaddr_t);
+STATIC void __pmap_pv_remove(pmap_t, struct vm_page *, vaddr_t);
+STATIC void *__pmap_pv_page_alloc(struct pool *, int);
+STATIC void __pmap_pv_page_free(struct pool *, void *);
+STATIC struct pool __pmap_pv_pool;
+STATIC struct pool_allocator pmap_pv_page_allocator = {
+ __pmap_pv_page_alloc, __pmap_pv_page_free, 0,
+};
+
+/* ASID ops. */
+STATIC int __pmap_asid_alloc(void);
+STATIC void __pmap_asid_free(int);
+STATIC struct {
+ uint32_t map[8];
+ int hint; /* hint for next allocation */
+} __pmap_asid;
+
+/* page table entry ops. */
+STATIC pt_entry_t *__pmap_pte_alloc(pmap_t, vaddr_t);
+
+/* pmap_enter util */
+STATIC boolean_t __pmap_map_change(pmap_t, vaddr_t, paddr_t, vm_prot_t,
+ pt_entry_t);
+
+void
+pmap_bootstrap()
+{
+ /* Steal msgbuf area */
+ initmsgbuf((caddr_t)uvm_pageboot_alloc(MSGBUFSIZE), MSGBUFSIZE);
+
+ avail_start = ptoa(vm_physmem[0].start);
+ avail_end = ptoa(vm_physmem[vm_nphysseg - 1].end);
+ __pmap_kve = VM_MIN_KERNEL_ADDRESS;
+
+ pmap_kernel()->pm_refcnt = 1;
+ pmap_kernel()->pm_ptp = (pt_entry_t **)uvm_pageboot_alloc(PAGE_SIZE);
+ memset(pmap_kernel()->pm_ptp, 0, PAGE_SIZE);
+
+ /* Enable MMU */
+ sh_mmu_start();
+ /* Mask all interrupt */
+ _cpu_intr_suspend();
+ /* Enable exception for P3 access */
+ _cpu_exception_resume(0);
+}
+
+vaddr_t
+pmap_steal_memory(vsize_t size, vaddr_t *vstart, vaddr_t *vend)
+{
+ struct vm_physseg *bank;
+ int i, j, npage;
+ paddr_t pa;
+ vaddr_t va;
+
+ KDASSERT(!uvm.page_init_done);
+
+ size = round_page(size);
+ npage = atop(size);
+
+ for (i = 0, bank = &vm_physmem[i]; i < vm_nphysseg; i++, bank++)
+ if (npage <= bank->avail_end - bank->avail_start)
+ break;
+ KDASSERT(i != vm_nphysseg);
+
+ /* Steal pages */
+ pa = ptoa(bank->avail_start);
+ bank->avail_start += npage;
+ bank->start += npage;
+
+ /* GC memory bank */
+ if (bank->avail_start == bank->end) {
+ /* Remove this segment from the list. */
+ vm_nphysseg--;
+ KDASSERT(vm_nphysseg > 0);
+ for (j = i; i < vm_nphysseg; j++)
+ vm_physmem[j] = vm_physmem[j + 1];
+ }
+
+ va = SH3_PHYS_TO_P1SEG(pa);
+ memset((caddr_t)va, 0, size);
+
+ return (va);
+}
+
+vaddr_t
+pmap_growkernel(vaddr_t maxkvaddr)
+{
+ int i, n;
+
+ if (maxkvaddr <= __pmap_kve)
+ return (__pmap_kve);
+
+ i = __PMAP_PTP_INDEX(__pmap_kve - VM_MIN_KERNEL_ADDRESS);
+ __pmap_kve = __PMAP_PTP_TRUNC(maxkvaddr);
+ n = __PMAP_PTP_INDEX(__pmap_kve - VM_MIN_KERNEL_ADDRESS);
+
+ /* Allocate page table pages */
+ for (;i < n; i++) {
+ if (__pmap_kernel.pm_ptp[i] != NULL)
+ continue;
+
+ if (uvm.page_init_done) {
+ struct vm_page *pg = uvm_pagealloc(NULL, 0, NULL,
+ UVM_PGA_USERESERVE | UVM_PGA_ZERO);
+ if (pg == NULL)
+ goto error;
+ __pmap_kernel.pm_ptp[i] = (pt_entry_t *)
+ SH3_PHYS_TO_P1SEG(VM_PAGE_TO_PHYS(pg));
+ } else {
+ pt_entry_t *ptp = (pt_entry_t *)
+ uvm_pageboot_alloc(PAGE_SIZE);
+ if (ptp == NULL)
+ goto error;
+ __pmap_kernel.pm_ptp[i] = ptp;
+ memset(ptp, 0, PAGE_SIZE);
+ }
+ }
+
+ return (__pmap_kve);
+ error:
+ panic("pmap_growkernel: out of memory.");
+ /* NOTREACHED */
+}
+
+void
+pmap_virtual_space(vaddr_t *start, vaddr_t *end)
+{
+ *start = VM_MIN_KERNEL_ADDRESS;
+ *end = VM_MAX_KERNEL_ADDRESS;
+}
+
+void
+pmap_init()
+{
+ /* Initialize pmap module */
+ pool_init(&__pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl",
+ &pool_allocator_nointr);
+ pool_init(&__pmap_pv_pool, sizeof(struct pv_entry), 0, 0, 0, "pvpl",
+ &pmap_pv_page_allocator);
+ pool_setlowat(&__pmap_pv_pool, 16);
+}
+
+pmap_t
+pmap_create()
+{
+ pmap_t pmap;
+
+ pmap = pool_get(&__pmap_pmap_pool, PR_WAITOK);
+ memset(pmap, 0, sizeof(struct pmap));
+ pmap->pm_asid = -1;
+ pmap->pm_refcnt = 1;
+ /* Allocate page table page holder (512 slot) */
+ pmap->pm_ptp = (pt_entry_t **)
+ SH3_PHYS_TO_P1SEG(VM_PAGE_TO_PHYS(
+ uvm_pagealloc(NULL, 0, NULL,
+ UVM_PGA_USERESERVE | UVM_PGA_ZERO)));
+
+ return (pmap);
+}
+
+void
+pmap_destroy(pmap_t pmap)
+{
+ int i;
+
+ if (--pmap->pm_refcnt > 0)
+ return;
+
+ /* Deallocate all page table page */
+ for (i = 0; i < __PMAP_PTP_N; i++) {
+ vaddr_t va = (vaddr_t)pmap->pm_ptp[i];
+ if (va == 0)
+ continue;
+#ifdef DEBUG /* Check no mapping exists. */
+ {
+ int j;
+ pt_entry_t *pte = (pt_entry_t *)va;
+ for (j = 0; j < __PMAP_PTP_PG_N; j++, pte++)
+ KDASSERT(*pte == 0);
+ }
+#endif /* DEBUG */
+ /* Purge cache entry for next use of this page. */
+ if (SH_HAS_VIRTUAL_ALIAS)
+ sh_dcache_inv_range(va, PAGE_SIZE);
+ /* Free page table */
+ uvm_pagefree(PHYS_TO_VM_PAGE(SH3_P1SEG_TO_PHYS(va)));
+ }
+ /* Deallocate page table page holder */
+ if (SH_HAS_VIRTUAL_ALIAS)
+ sh_dcache_inv_range((vaddr_t)pmap->pm_ptp, PAGE_SIZE);
+ uvm_pagefree(PHYS_TO_VM_PAGE(SH3_P1SEG_TO_PHYS((vaddr_t)pmap->pm_ptp)));
+
+ /* Free ASID */
+ __pmap_asid_free(pmap->pm_asid);
+
+ pool_put(&__pmap_pmap_pool, pmap);
+}
+
+void
+pmap_reference(pmap_t pmap)
+{
+ pmap->pm_refcnt++;
+}
+
+void
+pmap_activate(struct proc *p)
+{
+ pmap_t pmap = p->p_vmspace->vm_map.pmap;
+
+ if (pmap->pm_asid == -1)
+ pmap->pm_asid = __pmap_asid_alloc();
+
+ KDASSERT(pmap->pm_asid >=0 && pmap->pm_asid < 256);
+ sh_tlb_set_asid(pmap->pm_asid);
+}
+
+int
+pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
+{
+ struct vm_page *pg;
+ struct vm_page_md *pvh;
+ pt_entry_t entry, *pte;
+ boolean_t kva = (pmap == pmap_kernel());
+
+ /* "flags" never exceed "prot" */
+ KDASSERT(prot != 0 && ((flags & VM_PROT_ALL) & ~prot) == 0);
+
+ pg = PHYS_TO_VM_PAGE(pa);
+ entry = (pa & PG_PPN) | PG_4K;
+ if (flags & PMAP_WIRED)
+ entry |= _PG_WIRED;
+
+ if (pg != NULL) { /* memory-space */
+ pvh = &pg->mdpage;
+ entry |= PG_C; /* always cached */
+
+ /* Modified/reference tracking */
+ if (flags & VM_PROT_WRITE) {
+ entry |= PG_V | PG_D;
+ pvh->pvh_flags |= PVH_MODIFIED | PVH_REFERENCED;
+ } else if (flags & VM_PROT_ALL) {
+ entry |= PG_V;
+ pvh->pvh_flags |= PVH_REFERENCED;
+ }
+
+ /* Protection */
+ if ((prot & VM_PROT_WRITE) && (pvh->pvh_flags & PVH_MODIFIED)) {
+ if (kva)
+ entry |= PG_PR_KRW | PG_SH;
+ else
+ entry |= PG_PR_URW;
+ } else {
+ /* RO, COW page */
+ if (kva)
+ entry |= PG_PR_KRO | PG_SH;
+ else
+ entry |= PG_PR_URO;
+ }
+
+ /* Check for existing mapping */
+ if (__pmap_map_change(pmap, va, pa, prot, entry))
+ return (0);
+
+ /* Add to physical-virtual map list of this page */
+ __pmap_pv_enter(pmap, pg, va);
+
+ } else { /* bus-space (always uncached map) */
+ if (kva) {
+ entry |= PG_V | PG_SH |
+ ((prot & VM_PROT_WRITE) ?
+ (PG_PR_KRW | PG_D) : PG_PR_KRO);
+ } else {
+ entry |= PG_V |
+ ((prot & VM_PROT_WRITE) ?
+ (PG_PR_URW | PG_D) : PG_PR_URO);
+ }
+ }
+
+ /* Register to page table */
+ if (kva)
+ pte = __pmap_kpte_lookup(va);
+ else {
+ pte = __pmap_pte_alloc(pmap, va);
+ if (pte == NULL) {
+ if (flags & PMAP_CANFAIL)
+ return ENOMEM;
+ panic("pmap_enter: cannot allocate pte");
+ }
+ }
+
+ *pte = entry;
+
+ if (pmap->pm_asid != -1)
+ sh_tlb_update(pmap->pm_asid, va, entry);
+
+ if (!SH_HAS_UNIFIED_CACHE &&
+ (prot == (VM_PROT_READ | VM_PROT_EXECUTE)))
+ sh_icache_sync_range_index(va, PAGE_SIZE);
+
+ if (entry & _PG_WIRED)
+ pmap->pm_stats.wired_count++;
+ pmap->pm_stats.resident_count++;
+
+ return (0);
+}
+
+/*
+ * boolean_t __pmap_map_change(pmap_t pmap, vaddr_t va, paddr_t pa,
+ * vm_prot_t prot, pt_entry_t entry):
+ * Handle the situation that pmap_enter() is called to enter a
+ * mapping at a virtual address for which a mapping already
+ * exists.
+ */
+boolean_t
+__pmap_map_change(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot,
+ pt_entry_t entry)
+{
+ pt_entry_t *pte, oentry;
+ vaddr_t eva = va + PAGE_SIZE;
+
+ if ((pte = __pmap_pte_lookup(pmap, va)) == NULL ||
+ ((oentry = *pte) == 0))
+ return (FALSE); /* no mapping exists. */
+
+ if (pa != (oentry & PG_PPN)) {
+ /* Enter a mapping at a mapping to another physical page. */
+ pmap_remove(pmap, va, eva);
+ return (FALSE);
+ }
+
+ /* Pre-existing mapping */
+
+ /* Protection change. */
+ if ((oentry & PG_PR_MASK) != (entry & PG_PR_MASK))
+ pmap_protect(pmap, va, eva, prot);
+
+ /* Wired change */
+ if (oentry & _PG_WIRED) {
+ if (!(entry & _PG_WIRED)) {
+ /* wired -> unwired */
+ *pte = entry;
+ /* "wired" is software bits. no need to update TLB */
+ pmap->pm_stats.wired_count--;
+ }
+ } else if (entry & _PG_WIRED) {
+ /* unwired -> wired. make sure to reflect "flags" */
+ pmap_remove(pmap, va, eva);
+ return (FALSE);
+ }
+
+ return (TRUE); /* mapping was changed. */
+}
+
+/*
+ * void __pmap_pv_enter(pmap_t pmap, struct vm_page *pg, vaddr_t vaddr):
+ * Insert physical-virtual map to vm_page.
+ * Assume pre-existed mapping is already removed.
+ */
+void
+__pmap_pv_enter(pmap_t pmap, struct vm_page *pg, vaddr_t va)
+{
+ struct vm_page_md *pvh;
+ struct pv_entry *pv;
+ int s;
+
+ s = splvm();
+ if (SH_HAS_VIRTUAL_ALIAS) {
+ /* Remove all other mapping on this physical page */
+ pvh = &pg->mdpage;
+ while ((pv = SLIST_FIRST(&pvh->pvh_head)) != NULL) {
+ pmap_remove(pv->pv_pmap, pv->pv_va,
+ pv->pv_va + PAGE_SIZE);
+ }
+ }
+
+ /* Register pv map */
+ pvh = &pg->mdpage;
+ pv = __pmap_pv_alloc();
+ pv->pv_pmap = pmap;
+ pv->pv_va = va;
+
+ SLIST_INSERT_HEAD(&pvh->pvh_head, pv, pv_link);
+ splx(s);
+}
+
+void
+pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva)
+{
+ struct vm_page *pg;
+ pt_entry_t *pte, entry;
+ vaddr_t va;
+
+ KDASSERT((sva & PGOFSET) == 0);
+
+ for (va = sva; va < eva; va += PAGE_SIZE) {
+ if ((pte = __pmap_pte_lookup(pmap, va)) == NULL ||
+ (entry = *pte) == 0)
+ continue;
+
+ if ((pg = PHYS_TO_VM_PAGE(entry & PG_PPN)) != NULL)
+ __pmap_pv_remove(pmap, pg, va);
+
+ if (entry & _PG_WIRED)
+ pmap->pm_stats.wired_count--;
+ pmap->pm_stats.resident_count--;
+ *pte = 0;
+
+ /*
+ * When pmap->pm_asid == -1 (invalid ASID), old entry attribute
+ * to this pmap is already removed by pmap_activate().
+ */
+ if (pmap->pm_asid != -1)
+ sh_tlb_invalidate_addr(pmap->pm_asid, va);
+ }
+}
+
+/*
+ * void __pmap_pv_remove(pmap_t pmap, struct vm_page *pg, vaddr_t vaddr):
+ * Remove physical-virtual map from vm_page.
+ */
+void
+__pmap_pv_remove(pmap_t pmap, struct vm_page *pg, vaddr_t vaddr)
+{
+ struct vm_page_md *pvh;
+ struct pv_entry *pv;
+ int s;
+
+ s = splvm();
+ pvh = &pg->mdpage;
+ SLIST_FOREACH(pv, &pvh->pvh_head, pv_link) {
+ if (pv->pv_pmap == pmap && pv->pv_va == vaddr) {
+ if (SH_HAS_VIRTUAL_ALIAS ||
+ (SH_HAS_WRITEBACK_CACHE &&
+ (pg->mdpage.pvh_flags & PVH_MODIFIED))) {
+ /*
+ * Always use index ops. since I don't want to
+ * worry about address space.
+ */
+ sh_dcache_wbinv_range_index
+ (pv->pv_va, PAGE_SIZE);
+ }
+
+ SLIST_REMOVE(&pvh->pvh_head, pv, pv_entry, pv_link);
+ __pmap_pv_free(pv);
+ break;
+ }
+ }
+#ifdef DEBUG
+ /* Check duplicated map. */
+ SLIST_FOREACH(pv, &pvh->pvh_head, pv_link)
+ KDASSERT(!(pv->pv_pmap == pmap && pv->pv_va == vaddr));
+#endif
+ splx(s);
+}
+
+void
+pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
+{
+ pt_entry_t *pte, entry;
+
+ KDASSERT((va & PGOFSET) == 0);
+ KDASSERT(va >= VM_MIN_KERNEL_ADDRESS && va < VM_MAX_KERNEL_ADDRESS);
+
+ entry = (pa & PG_PPN) | PG_V | PG_SH | PG_4K;
+ if (prot & VM_PROT_WRITE)
+ entry |= (PG_PR_KRW | PG_D);
+ else
+ entry |= PG_PR_KRO;
+
+ if (PHYS_TO_VM_PAGE(pa))
+ entry |= PG_C;
+
+ pte = __pmap_kpte_lookup(va);
+
+ KDASSERT(*pte == 0);
+ *pte = entry;
+
+ sh_tlb_update(0, va, entry);
+}
+
+void
+pmap_kremove(vaddr_t va, vsize_t len)
+{
+ pt_entry_t *pte;
+ vaddr_t eva = va + len;
+
+ KDASSERT((va & PGOFSET) == 0);
+ KDASSERT((len & PGOFSET) == 0);
+ KDASSERT(va >= VM_MIN_KERNEL_ADDRESS && eva <= VM_MAX_KERNEL_ADDRESS);
+
+ for (; va < eva; va += PAGE_SIZE) {
+ pte = __pmap_kpte_lookup(va);
+ KDASSERT(pte != NULL);
+ if (*pte == 0)
+ continue;
+
+ if (SH_HAS_VIRTUAL_ALIAS && PHYS_TO_VM_PAGE(*pte & PG_PPN))
+ sh_dcache_wbinv_range(va, PAGE_SIZE);
+ *pte = 0;
+
+ sh_tlb_invalidate_addr(0, va);
+ }
+}
+
+boolean_t
+pmap_extract(pmap_t pmap, vaddr_t va, paddr_t *pap)
+{
+ pt_entry_t *pte;
+
+ /* handle P1 and P2 specially: va == pa */
+ if (pmap == pmap_kernel() && (va >> 30) == 2) {
+ if (pap != NULL)
+ *pap = va & SH3_PHYS_MASK;
+ return (TRUE);
+ }
+
+ pte = __pmap_pte_lookup(pmap, va);
+ if (pte == NULL || *pte == 0)
+ return (FALSE);
+
+ if (pap != NULL)
+ *pap = (*pte & PG_PPN) | (va & PGOFSET);
+
+ return (TRUE);
+}
+
+void
+pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
+{
+ boolean_t kernel = pmap == pmap_kernel();
+ pt_entry_t *pte, entry;
+ vaddr_t va;
+
+ sva = trunc_page(sva);
+
+ if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
+ pmap_remove(pmap, sva, eva);
+ return;
+ }
+
+ for (va = sva; va < eva; va += PAGE_SIZE) {
+
+ if (((pte = __pmap_pte_lookup(pmap, va)) == NULL) ||
+ (entry = *pte) == 0)
+ continue;
+
+ if (SH_HAS_VIRTUAL_ALIAS && (entry & PG_D)) {
+ if (!SH_HAS_UNIFIED_CACHE && (prot & VM_PROT_EXECUTE))
+ sh_icache_sync_range_index(va, PAGE_SIZE);
+ else
+ sh_dcache_wbinv_range_index(va, PAGE_SIZE);
+ }
+
+ entry &= ~PG_PR_MASK;
+ switch (prot) {
+ default:
+ panic("pmap_protect: invalid protection mode %x", prot);
+ /* NOTREACHED */
+ case VM_PROT_READ:
+ /* FALLTHROUGH */
+ case VM_PROT_READ | VM_PROT_EXECUTE:
+ entry |= kernel ? PG_PR_KRO : PG_PR_URO;
+ break;
+ case VM_PROT_READ | VM_PROT_WRITE:
+ /* FALLTHROUGH */
+ case VM_PROT_ALL:
+ entry |= kernel ? PG_PR_KRW : PG_PR_URW;
+ break;
+ }
+ *pte = entry;
+
+ if (pmap->pm_asid != -1)
+ sh_tlb_update(pmap->pm_asid, va, entry);
+ }
+}
+
+void
+pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
+{
+ struct vm_page_md *pvh = &pg->mdpage;
+ struct pv_entry *pv;
+ struct pmap *pmap;
+ vaddr_t va;
+ int s;
+
+ switch (prot) {
+ case VM_PROT_READ | VM_PROT_WRITE:
+ /* FALLTHROUGH */
+ case VM_PROT_ALL:
+ break;
+
+ case VM_PROT_READ:
+ /* FALLTHROUGH */
+ case VM_PROT_READ | VM_PROT_EXECUTE:
+ s = splvm();
+ SLIST_FOREACH(pv, &pvh->pvh_head, pv_link) {
+ pmap = pv->pv_pmap;
+ va = pv->pv_va;
+
+ KDASSERT(pmap);
+ pmap_protect(pmap, va, va + PAGE_SIZE, prot);
+ }
+ splx(s);
+ break;
+
+ default:
+ /* Remove all */
+ s = splvm();
+ while ((pv = SLIST_FIRST(&pvh->pvh_head)) != NULL) {
+ va = pv->pv_va;
+ pmap_remove(pv->pv_pmap, va, va + PAGE_SIZE);
+ }
+ splx(s);
+ }
+}
+
+void
+pmap_unwire(pmap_t pmap, vaddr_t va)
+{
+ pt_entry_t *pte, entry;
+
+ if ((pte = __pmap_pte_lookup(pmap, va)) == NULL ||
+ (entry = *pte) == 0 ||
+ (entry & _PG_WIRED) == 0)
+ return;
+
+ *pte = entry & ~_PG_WIRED;
+ pmap->pm_stats.wired_count--;
+}
+
+void
+pmap_proc_iflush(struct proc *p, vaddr_t va, size_t len)
+{
+ if (!SH_HAS_UNIFIED_CACHE)
+ sh_icache_sync_range_index(va, len);
+}
+
+void
+pmap_zero_page(vm_page_t pg)
+{
+ paddr_t phys = VM_PAGE_TO_PHYS(pg);
+
+ if (SH_HAS_VIRTUAL_ALIAS) { /* don't pollute cache */
+ /* sync cache since we access via P2. */
+ sh_dcache_wbinv_all();
+ memset((void *)SH3_PHYS_TO_P2SEG(phys), 0, PAGE_SIZE);
+ } else {
+ memset((void *)SH3_PHYS_TO_P1SEG(phys), 0, PAGE_SIZE);
+ }
+}
+
+void
+pmap_copy_page(vm_page_t srcpg, vm_page_t dstpg)
+{
+ paddr_t src,dst;
+
+ src = VM_PAGE_TO_PHYS(srcpg);
+ dst = VM_PAGE_TO_PHYS(dstpg);
+
+ if (SH_HAS_VIRTUAL_ALIAS) { /* don't pollute cache */
+ /* sync cache since we access via P2. */
+ sh_dcache_wbinv_all();
+ memcpy((void *)SH3_PHYS_TO_P2SEG(dst),
+ (void *)SH3_PHYS_TO_P2SEG(src), PAGE_SIZE);
+ } else {
+ memcpy((void *)SH3_PHYS_TO_P1SEG(dst),
+ (void *)SH3_PHYS_TO_P1SEG(src), PAGE_SIZE);
+ }
+}
+
+boolean_t
+pmap_is_referenced(struct vm_page *pg)
+{
+ return ((pg->mdpage.pvh_flags & PVH_REFERENCED) ? TRUE : FALSE);
+}
+
+boolean_t
+pmap_clear_reference(struct vm_page *pg)
+{
+ struct vm_page_md *pvh = &pg->mdpage;
+ struct pv_entry *pv;
+ pt_entry_t *pte;
+ pmap_t pmap;
+ vaddr_t va;
+ int s;
+
+ if ((pg->mdpage.pvh_flags & PVH_REFERENCED) == 0)
+ return (FALSE);
+
+ pg->mdpage.pvh_flags &= ~PVH_REFERENCED;
+
+ s = splvm();
+ /* Restart reference bit emulation */
+ SLIST_FOREACH(pv, &pvh->pvh_head, pv_link) {
+ pmap = pv->pv_pmap;
+ va = pv->pv_va;
+
+ if ((pte = __pmap_pte_lookup(pmap, va)) == NULL)
+ continue;
+ if ((*pte & PG_V) == 0)
+ continue;
+ *pte &= ~PG_V;
+
+ if (pmap->pm_asid != -1)
+ sh_tlb_invalidate_addr(pmap->pm_asid, va);
+ }
+ splx(s);
+
+ return (TRUE);
+}
+
+boolean_t
+pmap_is_modified(struct vm_page *pg)
+{
+ return ((pg->mdpage.pvh_flags & PVH_MODIFIED) ? TRUE : FALSE);
+}
+
+boolean_t
+pmap_clear_modify(struct vm_page *pg)
+{
+ struct vm_page_md *pvh = &pg->mdpage;
+ struct pv_entry *pv;
+ struct pmap *pmap;
+ pt_entry_t *pte, entry;
+ boolean_t modified;
+ vaddr_t va;
+ int s;
+
+ modified = pvh->pvh_flags & PVH_MODIFIED;
+ if (!modified)
+ return (FALSE);
+
+ pvh->pvh_flags &= ~PVH_MODIFIED;
+
+ s = splvm();
+ if (SLIST_EMPTY(&pvh->pvh_head)) {/* no map on this page */
+ splx(s);
+ return (TRUE);
+ }
+
+ /* Write-back and invalidate TLB entry */
+ if (!SH_HAS_VIRTUAL_ALIAS && SH_HAS_WRITEBACK_CACHE)
+ sh_dcache_wbinv_all();
+
+ SLIST_FOREACH(pv, &pvh->pvh_head, pv_link) {
+ pmap = pv->pv_pmap;
+ va = pv->pv_va;
+ if ((pte = __pmap_pte_lookup(pmap, va)) == NULL)
+ continue;
+ entry = *pte;
+ if ((entry & PG_D) == 0)
+ continue;
+
+ if (SH_HAS_VIRTUAL_ALIAS)
+ sh_dcache_wbinv_range_index(va, PAGE_SIZE);
+
+ *pte = entry & ~PG_D;
+ if (pmap->pm_asid != -1)
+ sh_tlb_invalidate_addr(pmap->pm_asid, va);
+ }
+ splx(s);
+
+ return (TRUE);
+}
+
+/*
+ * pv_entry pool allocator:
+ * void *__pmap_pv_page_alloc(struct pool *pool, int flags):
+ * void __pmap_pv_page_free(struct pool *pool, void *v):
+ */
+void *
+__pmap_pv_page_alloc(struct pool *pool, int flags)
+{
+ struct vm_page *pg;
+
+ pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_USERESERVE);
+ if (pg == NULL)
+ return (NULL);
+
+ return ((void *)SH3_PHYS_TO_P1SEG(VM_PAGE_TO_PHYS(pg)));
+}
+
+void
+__pmap_pv_page_free(struct pool *pool, void *v)
+{
+ vaddr_t va = (vaddr_t)v;
+
+ /* Invalidate cache for next use of this page */
+ if (SH_HAS_VIRTUAL_ALIAS)
+ sh_icache_sync_range_index(va, PAGE_SIZE);
+ uvm_pagefree(PHYS_TO_VM_PAGE(SH3_P1SEG_TO_PHYS(va)));
+}
+
+/*
+ * pt_entry_t __pmap_pte_alloc(pmap_t pmap, vaddr_t va):
+ * lookup page table entry. if found returns it, else allocate it.
+ * page table is accessed via P1.
+ */
+pt_entry_t *
+__pmap_pte_alloc(pmap_t pmap, vaddr_t va)
+{
+ struct vm_page *pg;
+ pt_entry_t *ptp, *pte;
+
+ if ((pte = __pmap_pte_lookup(pmap, va)) != NULL)
+ return (pte);
+
+ /* Allocate page table (not managed page) */
+ pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_USERESERVE | UVM_PGA_ZERO);
+ if (pg == NULL)
+ return NULL;
+
+ ptp = (pt_entry_t *)SH3_PHYS_TO_P1SEG(VM_PAGE_TO_PHYS(pg));
+ pmap->pm_ptp[__PMAP_PTP_INDEX(va)] = ptp;
+
+ return (ptp + __PMAP_PTP_OFSET(va));
+}
+
+/*
+ * pt_entry_t *__pmap_pte_lookup(pmap_t pmap, vaddr_t va):
+ * lookup page table entry, if not allocated, returns NULL.
+ */
+pt_entry_t *
+__pmap_pte_lookup(pmap_t pmap, vaddr_t va)
+{
+ pt_entry_t *ptp;
+
+ if (pmap == pmap_kernel())
+ return (__pmap_kpte_lookup(va));
+
+ /* Lookup page table page */
+ ptp = pmap->pm_ptp[__PMAP_PTP_INDEX(va)];
+ if (ptp == NULL)
+ return (NULL);
+
+ return (ptp + __PMAP_PTP_OFSET(va));
+}
+
+/*
+ * pt_entry_t *__pmap_kpte_lookup(vaddr_t va):
+ * kernel virtual only version of __pmap_pte_lookup().
+ */
+pt_entry_t *
+__pmap_kpte_lookup(vaddr_t va)
+{
+ return (__pmap_kernel.pm_ptp
+ [__PMAP_PTP_INDEX(va - VM_MIN_KERNEL_ADDRESS)] +
+ __PMAP_PTP_OFSET(va));
+}
+
+/*
+ * boolean_t __pmap_pte_load(pmap_t pmap, vaddr_t va, int flags):
+ * lookup page table entry, if found it, load to TLB.
+ * flags specify do emulate reference and/or modified bit or not.
+ */
+boolean_t
+__pmap_pte_load(pmap_t pmap, vaddr_t va, int flags)
+{
+ struct vm_page *pg;
+ pt_entry_t *pte;
+ pt_entry_t entry;
+
+ KDASSERT((((int)va < 0) && (pmap == pmap_kernel())) ||
+ (((int)va >= 0) && (pmap != pmap_kernel())));
+
+ /* Lookup page table entry */
+ if (((pte = __pmap_pte_lookup(pmap, va)) == NULL) ||
+ ((entry = *pte) == 0))
+ return (FALSE);
+
+ KDASSERT(va != 0);
+
+ /* Emulate reference/modified tracking for managed page. */
+ if (flags != 0 && (pg = PHYS_TO_VM_PAGE(entry & PG_PPN)) != NULL) {
+ if (flags & PVH_REFERENCED) {
+ pg->mdpage.pvh_flags |= PVH_REFERENCED;
+ entry |= PG_V;
+ }
+ if (flags & PVH_MODIFIED) {
+ pg->mdpage.pvh_flags |= PVH_MODIFIED;
+ entry |= PG_D;
+ }
+ *pte = entry;
+ }
+
+ /* When pmap has valid ASID, register to TLB */
+ if (pmap->pm_asid != -1)
+ sh_tlb_update(pmap->pm_asid, va, entry);
+
+ return (TRUE);
+}
+
+/*
+ * int __pmap_asid_alloc(void):
+ * Allocate new ASID. if all ASID is used, steal from other process.
+ */
+int
+__pmap_asid_alloc()
+{
+ struct proc *p;
+ int i, j, k, n, map, asid;
+
+ /* Search free ASID */
+ i = __pmap_asid.hint >> 5;
+ n = i + 8;
+ for (; i < n; i++) {
+ k = i & 0x7;
+ map = __pmap_asid.map[k];
+ for (j = 0; j < 32; j++) {
+ if ((map & (1 << j)) == 0 && (k + j) != 0) {
+ __pmap_asid.map[k] |= (1 << j);
+ __pmap_asid.hint = (k << 5) + j;
+ return (__pmap_asid.hint);
+ }
+ }
+ }
+
+ /* Steal ASID */
+ LIST_FOREACH(p, &allproc, p_list) {
+ if ((asid = p->p_vmspace->vm_map.pmap->pm_asid) > 0) {
+ pmap_t pmap = p->p_vmspace->vm_map.pmap;
+ pmap->pm_asid = -1;
+ __pmap_asid.hint = asid;
+ /* Invalidate all old ASID entry */
+ sh_tlb_invalidate_asid(pmap->pm_asid);
+
+ return (__pmap_asid.hint);
+ }
+ }
+
+ panic("No ASID allocated.");
+ /* NOTREACHED */
+}
+
+/*
+ * void __pmap_asid_free(int asid):
+ * Return unused ASID to pool. and remove all TLB entry of ASID.
+ */
+void
+__pmap_asid_free(int asid)
+{
+ int i;
+
+ if (asid < 1) /* Don't invalidate kernel ASID 0 */
+ return;
+
+ sh_tlb_invalidate_asid(asid);
+
+ i = asid >> 5;
+ __pmap_asid.map[i] &= ~(1 << (asid - (i << 5)));
+}
diff --git a/sys/arch/sh/sh/process_machdep.c b/sys/arch/sh/sh/process_machdep.c
new file mode 100644
index 00000000000..9f82c48527a
--- /dev/null
+++ b/sys/arch/sh/sh/process_machdep.c
@@ -0,0 +1,210 @@
+/* $OpenBSD: process_machdep.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: process_machdep.c,v 1.12 2006/01/21 04:12:22 uwe Exp $ */
+
+/*
+ * Copyright (c) 1993 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * From:
+ * Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel
+ */
+
+/*
+ * Copyright (c) 1995, 1996, 1997
+ * Charles M. Hannum. All rights reserved.
+ * Copyright (c) 1993 Jan-Simon Pendry
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * From:
+ * Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel
+ */
+
+/*
+ * This file may seem a bit stylized, but that so that it's easier to port.
+ * Functions to be implemented here are:
+ *
+ * process_read_regs(proc, regs)
+ * Get the current user-visible register set from the process
+ * and copy it into the regs structure (<machine/reg.h>).
+ * The process is stopped at the time read_regs is called.
+ *
+ * process_write_regs(proc, regs)
+ * Update the current register set from the passed in regs
+ * structure. Take care to avoid clobbering special CPU
+ * registers or privileged bits in the PSL.
+ * The process is stopped at the time write_regs is called.
+ *
+ * process_sstep(proc)
+ * Arrange for the process to trap after executing a single instruction.
+ *
+ * process_set_pc(proc)
+ * Set the process's program counter.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/vnode.h>
+#include <sys/ptrace.h>
+
+#include <machine/psl.h>
+#include <machine/reg.h>
+
+static inline struct trapframe *
+process_frame(struct proc *p)
+{
+
+ return (p->p_md.md_regs);
+}
+
+int
+process_read_regs(struct proc *p, struct reg *regs)
+{
+ struct trapframe *tf = process_frame(p);
+
+ regs->r_spc = tf->tf_spc;
+ regs->r_ssr = tf->tf_ssr;
+ regs->r_macl = tf->tf_macl;
+ regs->r_mach = tf->tf_mach;
+ regs->r_pr = tf->tf_pr;
+ regs->r_r14 = tf->tf_r14;
+ regs->r_r13 = tf->tf_r13;
+ regs->r_r12 = tf->tf_r12;
+ regs->r_r11 = tf->tf_r11;
+ regs->r_r10 = tf->tf_r10;
+ regs->r_r9 = tf->tf_r9;
+ regs->r_r8 = tf->tf_r8;
+ regs->r_r7 = tf->tf_r7;
+ regs->r_r6 = tf->tf_r6;
+ regs->r_r5 = tf->tf_r5;
+ regs->r_r4 = tf->tf_r4;
+ regs->r_r3 = tf->tf_r3;
+ regs->r_r2 = tf->tf_r2;
+ regs->r_r1 = tf->tf_r1;
+ regs->r_r0 = tf->tf_r0;
+ regs->r_r15 = tf->tf_r15;
+
+ return (0);
+}
+
+#ifdef PTRACE
+
+int
+process_write_regs(struct proc *p, struct reg *regs)
+{
+ struct trapframe *tf = process_frame(p);
+
+ /*
+ * Check for security violations.
+ */
+ if (((regs->r_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) {
+ return (EINVAL);
+ }
+
+ tf->tf_spc = regs->r_spc;
+ tf->tf_ssr = regs->r_ssr;
+ tf->tf_pr = regs->r_pr;
+
+ tf->tf_mach = regs->r_mach;
+ tf->tf_macl = regs->r_macl;
+ tf->tf_r14 = regs->r_r14;
+ tf->tf_r13 = regs->r_r13;
+ tf->tf_r12 = regs->r_r12;
+ tf->tf_r11 = regs->r_r11;
+ tf->tf_r10 = regs->r_r10;
+ tf->tf_r9 = regs->r_r9;
+ tf->tf_r8 = regs->r_r8;
+ tf->tf_r7 = regs->r_r7;
+ tf->tf_r6 = regs->r_r6;
+ tf->tf_r5 = regs->r_r5;
+ tf->tf_r4 = regs->r_r4;
+ tf->tf_r3 = regs->r_r3;
+ tf->tf_r2 = regs->r_r2;
+ tf->tf_r1 = regs->r_r1;
+ tf->tf_r0 = regs->r_r0;
+ tf->tf_r15 = regs->r_r15;
+
+ return (0);
+}
+
+int
+process_sstep(struct proc *p, int sstep)
+{
+ if (sstep)
+ return (EINVAL);
+
+ return (0);
+}
+
+int
+process_set_pc(struct proc *p, caddr_t addr)
+{
+ struct trapframe *tf = process_frame(p);
+
+ tf->tf_spc = (int)addr;
+
+ return (0);
+}
+
+#endif /* PTRACE */
diff --git a/sys/arch/sh/sh/sh_machdep.c b/sys/arch/sh/sh/sh_machdep.c
new file mode 100644
index 00000000000..74ab7da4861
--- /dev/null
+++ b/sys/arch/sh/sh/sh_machdep.c
@@ -0,0 +1,471 @@
+/* $OpenBSD: sh_machdep.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: sh3_machdep.c,v 1.59 2006/03/04 01:13:36 uwe Exp $ */
+
+/*-
+ * Copyright (c) 1996, 1997, 1998, 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum and 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) 1982, 1987, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)machdep.c 7.4 (Berkeley) 6/3/91
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sys/buf.h>
+#include <sys/exec.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/syscallargs.h>
+#include <sys/user.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <sh/cache.h>
+#include <sh/clock.h>
+#include <sh/locore.h>
+#include <sh/mmu.h>
+#include <sh/trap.h>
+#include <sh/intr.h>
+
+/* Our exported CPU info; we can have only one. */
+int cpu_arch;
+int cpu_product;
+char cpu_model[120];
+
+struct vm_map *exec_map;
+struct vm_map *phys_map;
+
+int physmem;
+struct user *proc0paddr; /* init_main.c use this. */
+struct pcb *curpcb;
+struct md_upte *curupte; /* SH3 wired u-area hack */
+
+#define VBR (uint8_t *)SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN)
+vaddr_t ram_start = SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN);
+/* exception handler holder (sh/sh/vectors.S) */
+extern char sh_vector_generic[], sh_vector_generic_end[];
+extern char sh_vector_interrupt[], sh_vector_interrupt_end[];
+#ifdef SH3
+extern char sh3_vector_tlbmiss[], sh3_vector_tlbmiss_end[];
+#endif
+#ifdef SH4
+extern char sh4_vector_tlbmiss[], sh4_vector_tlbmiss_end[];
+#endif
+
+/*
+ * These variables are needed by /sbin/savecore
+ */
+uint32_t dumpmag = 0x8fca0101; /* magic number */
+int dumpsize; /* pages */
+long dumplo; /* blocks */
+
+void
+sh_cpu_init(int arch, int product)
+{
+ /* CPU type */
+ cpu_arch = arch;
+ cpu_product = product;
+
+#if defined(SH3) && defined(SH4)
+ /* Set register addresses */
+ sh_devreg_init();
+#endif
+ /* Cache access ops. */
+ sh_cache_init();
+
+ /* MMU access ops. */
+ sh_mmu_init();
+
+ /* Hardclock, RTC initialize. */
+ machine_clock_init();
+
+ /* ICU initiailze. */
+ intc_init();
+
+ /* Exception vector. */
+ memcpy(VBR + 0x100, sh_vector_generic,
+ sh_vector_generic_end - sh_vector_generic);
+#ifdef SH3
+ if (CPU_IS_SH3)
+ memcpy(VBR + 0x400, sh3_vector_tlbmiss,
+ sh3_vector_tlbmiss_end - sh3_vector_tlbmiss);
+#endif
+#ifdef SH4
+ if (CPU_IS_SH4)
+ memcpy(VBR + 0x400, sh4_vector_tlbmiss,
+ sh4_vector_tlbmiss_end - sh4_vector_tlbmiss);
+#endif
+ memcpy(VBR + 0x600, sh_vector_interrupt,
+ sh_vector_interrupt_end - sh_vector_interrupt);
+
+ if (!SH_HAS_UNIFIED_CACHE)
+ sh_icache_sync_all();
+
+ __asm volatile("ldc %0, vbr" :: "r"(VBR));
+
+ /* kernel stack setup */
+ __sh_switch_resume = CPU_IS_SH3 ? sh3_switch_resume : sh4_switch_resume;
+
+ /* Set page size (4KB) */
+ uvm_setpagesize();
+}
+
+/*
+ * void sh_proc0_init(void):
+ * Setup proc0 u-area.
+ */
+void
+sh_proc0_init()
+{
+ struct switchframe *sf;
+ vaddr_t u;
+
+ /* Steal process0 u-area */
+ u = uvm_pageboot_alloc(USPACE);
+ memset((void *)u, 0, USPACE);
+
+ /* Setup proc0 */
+ proc0paddr = (struct user *)u;
+ proc0.p_addr = proc0paddr;
+ /*
+ * u-area map:
+ * |user| .... | .................. |
+ * | PAGE_SIZE | USPACE - PAGE_SIZE |
+ * frame top stack top
+ * current frame ... r6_bank
+ * stack top ... r7_bank
+ * current stack ... r15
+ */
+ curpcb = proc0.p_md.md_pcb = &proc0.p_addr->u_pcb;
+ curupte = proc0.p_md.md_upte;
+
+ sf = &curpcb->pcb_sf;
+ sf->sf_r6_bank = u + PAGE_SIZE;
+ sf->sf_r7_bank = sf->sf_r15 = u + USPACE;
+ __asm volatile("ldc %0, r6_bank" :: "r"(sf->sf_r6_bank));
+ __asm volatile("ldc %0, r7_bank" :: "r"(sf->sf_r7_bank));
+
+ proc0.p_md.md_regs = (struct trapframe *)sf->sf_r6_bank - 1;
+#ifdef KSTACK_DEBUG
+ memset((char *)(u + sizeof(struct user)), 0x5a,
+ PAGE_SIZE - sizeof(struct user));
+ memset((char *)(u + PAGE_SIZE), 0xa5, USPACE - PAGE_SIZE);
+#endif /* KSTACK_DEBUG */
+}
+
+void
+sh_startup()
+{
+ vaddr_t minaddr, maxaddr;
+
+ printf("%s", version);
+ if (*cpu_model != '\0')
+ printf("%s", cpu_model);
+#ifdef DEBUG
+ printf("general exception handler:\t%d byte\n",
+ sh_vector_generic_end - sh_vector_generic);
+ printf("TLB miss exception handler:\t%d byte\n",
+#if defined(SH3) && defined(SH4)
+ CPU_IS_SH3 ? sh3_vector_tlbmiss_end - sh3_vector_tlbmiss :
+ sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
+#elif defined(SH3)
+ sh3_vector_tlbmiss_end - sh3_vector_tlbmiss
+#elif defined(SH4)
+ sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
+#endif
+ );
+ printf("interrupt exception handler:\t%d byte\n",
+ sh_vector_interrupt_end - sh_vector_interrupt);
+#endif /* DEBUG */
+
+ printf("real mem = %u (%uK)\n", ctob(physmem), ctob(physmem) / 1024);
+
+ minaddr = 0;
+ /*
+ * Allocate a submap for exec arguments. This map effectively
+ * limits the number of processes exec'ing at any time.
+ */
+ exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
+ 16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
+
+ /*
+ * Allocate a submap for physio
+ */
+ phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
+ VM_PHYS_SIZE, 0, FALSE, NULL);
+
+ printf("avail mem = %u (%uK)\n", ptoa(uvmexp.free),
+ ptoa(uvmexp.free) / 1024);
+}
+
+/*
+ * Signal frame.
+ */
+struct sigframe {
+#if 0 /* in registers on entry to signal trampoline */
+ int sf_signum; /* r4 - "signum" argument for handler */
+ siginfo_t *sf_sip; /* r5 - "sip" argument for handler */
+ struct sigcontext *sf_ucp; /* r6 - "ucp" argument for handler */
+#endif
+ struct sigcontext sf_uc; /* actual context */
+ siginfo_t sf_si;
+};
+
+/*
+ * Send an interrupt to process.
+ */
+void
+sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
+ union sigval val)
+{
+ struct proc *p = curproc;
+ struct sigframe *fp, frame;
+ struct trapframe *tf = p->p_md.md_regs;
+ struct sigacts *ps = p->p_sigacts;
+ siginfo_t *sip;
+ int onstack;
+
+ onstack = ps->ps_sigstk.ss_flags & SS_ONSTACK;
+ if ((ps->ps_flags & SAS_ALTSTACK) && onstack == 0 &&
+ (ps->ps_sigonstack & sigmask(sig))) {
+ fp = (struct sigframe *)((vaddr_t)ps->ps_sigstk.ss_sp +
+ ps->ps_sigstk.ss_size);
+ ps->ps_sigstk.ss_flags |= SS_ONSTACK;
+ } else
+ fp = (void *)p->p_md.md_regs->tf_r15;
+ --fp;
+
+
+ bzero(&frame, sizeof(frame));
+
+ if (ps->ps_siginfo & sigmask(sig)) {
+ initsiginfo(&frame.sf_si, sig, code, type, val);
+ sip = &fp->sf_si;
+ } else
+ sip = NULL;
+
+ /* Save register context. */
+ frame.sf_uc.sc_spc = tf->tf_spc;
+ frame.sf_uc.sc_ssr = tf->tf_ssr;
+ frame.sf_uc.sc_pr = tf->tf_pr;
+ frame.sf_uc.sc_r14 = tf->tf_r14;
+ frame.sf_uc.sc_r13 = tf->tf_r13;
+ frame.sf_uc.sc_r12 = tf->tf_r12;
+ frame.sf_uc.sc_r11 = tf->tf_r11;
+ frame.sf_uc.sc_r10 = tf->tf_r10;
+ frame.sf_uc.sc_r9 = tf->tf_r9;
+ frame.sf_uc.sc_r8 = tf->tf_r8;
+ frame.sf_uc.sc_r7 = tf->tf_r7;
+ frame.sf_uc.sc_r6 = tf->tf_r6;
+ frame.sf_uc.sc_r5 = tf->tf_r5;
+ frame.sf_uc.sc_r4 = tf->tf_r4;
+ frame.sf_uc.sc_r3 = tf->tf_r3;
+ frame.sf_uc.sc_r2 = tf->tf_r2;
+ frame.sf_uc.sc_r1 = tf->tf_r1;
+ frame.sf_uc.sc_r0 = tf->tf_r0;
+ frame.sf_uc.sc_r15 = tf->tf_r15;
+ frame.sf_uc.sc_onstack = onstack;
+ frame.sf_uc.sc_expevt = tf->tf_expevt;
+ /* frame.sf_uc.sc_err = 0; */
+ frame.sf_uc.sc_mask = p->p_sigmask;
+ /* XXX tf_macl, tf_mach not saved */
+
+ if (copyout(&frame, fp, sizeof(frame)) != 0) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+ sigexit(p, SIGILL);
+ /* NOTREACHED */
+ }
+
+ tf->tf_r4 = sig; /* "signum" argument for handler */
+ tf->tf_r5 = (int)sip; /* "sip" argument for handler */
+ tf->tf_r6 = (int)&fp->sf_uc; /* "ucp" argument for handler */
+ tf->tf_spc = (int)catcher;
+ tf->tf_r15 = (int)fp;
+ tf->tf_pr = (int)p->p_sigcode;
+}
+
+/*
+ * System call to cleanup state after a signal
+ * has been taken. Reset signal mask and
+ * stack state from context left by sendsig (above).
+ * Return to previous pc and psl as specified by
+ * context left by sendsig. Check carefully to
+ * make sure that the user has not modified the
+ * psl to gain improper privileges or to cause
+ * a machine fault.
+ */
+int
+sys_sigreturn(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_sigreturn_args /* {
+ syscallarg(struct sigcontext *) sigcntxp;
+ } */ *uap = v;
+ struct sigcontext *scp, context;
+ struct trapframe *tf;
+ int error;
+
+ /*
+ * The trampoline code hands us the context.
+ * It is unsafe to keep track of it ourselves, in the event that a
+ * program jumps out of a signal handler.
+ */
+ scp = SCARG(uap, sigcntxp);
+ if ((error = copyin((caddr_t)scp, &context, sizeof(*scp))) != 0)
+ return (error);
+
+ /* Restore signal context. */
+ tf = p->p_md.md_regs;
+
+ /* Check for security violations. */
+ if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0)
+ return (EINVAL);
+
+ tf->tf_ssr = context.sc_ssr;
+
+ tf->tf_r0 = context.sc_r0;
+ tf->tf_r1 = context.sc_r1;
+ tf->tf_r2 = context.sc_r2;
+ tf->tf_r3 = context.sc_r3;
+ tf->tf_r4 = context.sc_r4;
+ tf->tf_r5 = context.sc_r5;
+ tf->tf_r6 = context.sc_r6;
+ tf->tf_r7 = context.sc_r7;
+ tf->tf_r8 = context.sc_r8;
+ tf->tf_r9 = context.sc_r9;
+ tf->tf_r10 = context.sc_r10;
+ tf->tf_r11 = context.sc_r11;
+ tf->tf_r12 = context.sc_r12;
+ tf->tf_r13 = context.sc_r13;
+ tf->tf_r14 = context.sc_r14;
+ tf->tf_spc = context.sc_spc;
+ tf->tf_r15 = context.sc_r15;
+ tf->tf_pr = context.sc_pr;
+
+ /* Restore signal stack. */
+ if (context.sc_onstack)
+ p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
+ else
+ p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
+ /* Restore signal mask. */
+ p->p_sigmask = context.sc_mask & ~sigcantmask;
+
+ return (EJUSTRETURN);
+}
+
+/*
+ * Clear registers on exec
+ */
+void
+setregs(struct proc *p, struct exec_package *pack, u_long stack,
+ register_t rval[2])
+{
+ struct trapframe *tf;
+
+ p->p_md.md_flags &= ~MDP_USEDFPU;
+
+ tf = p->p_md.md_regs;
+
+ tf->tf_r0 = 0;
+ tf->tf_r1 = 0;
+ tf->tf_r2 = 0;
+ tf->tf_r3 = 0;
+ copyin((caddr_t)stack, &tf->tf_r4, sizeof(register_t)); /* argc */
+ tf->tf_r5 = stack + 4; /* argv */
+ tf->tf_r6 = stack + 4 * tf->tf_r4 + 8; /* envp */
+ tf->tf_r7 = 0;
+ tf->tf_r8 = 0;
+ tf->tf_r9 = (int)PS_STRINGS;
+ tf->tf_r10 = 0;
+ tf->tf_r11 = 0;
+ tf->tf_r12 = 0;
+ tf->tf_r13 = 0;
+ tf->tf_r14 = 0;
+ tf->tf_spc = pack->ep_entry;
+ tf->tf_ssr = PSL_USERSET;
+ tf->tf_r15 = stack;
+}
+
+/*
+ * Jump to reset vector.
+ */
+void
+cpu_reset()
+{
+ _cpu_exception_suspend();
+ _reg_write_4(SH_(EXPEVT), EXPEVT_RESET_MANUAL);
+
+#ifndef __lint__
+ goto *(void *)0xa0000000;
+#endif
+ /* NOTREACHED */
+}
diff --git a/sys/arch/sh/sh/sys_machdep.c b/sys/arch/sh/sh/sys_machdep.c
new file mode 100644
index 00000000000..3d78e981779
--- /dev/null
+++ b/sys/arch/sh/sh/sys_machdep.c
@@ -0,0 +1,87 @@
+/* $OpenBSD: sys_machdep.c,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: sys_machdep.c,v 1.11 2005/12/11 12:19:00 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91
+ */
+
+/*-
+ * Copyright (c) 1995, 1997
+ * Charles M. Hannum. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
+int
+sys_sysarch(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_sysarch_args __attribute__((__unused__)) *uap = v;
+
+ return (ENOSYS);
+}
diff --git a/sys/arch/sh/sh/trap.c b/sys/arch/sh/sh/trap.c
new file mode 100644
index 00000000000..c4da3df5a89
--- /dev/null
+++ b/sys/arch/sh/sh/trap.c
@@ -0,0 +1,618 @@
+/* $OpenBSD: trap.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: exception.c,v 1.32 2006/09/04 23:57:52 uwe Exp $ */
+/* $NetBSD: syscall.c,v 1.6 2006/03/07 07:21:50 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the University of Utah, and William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)trap.c 7.4 (Berkeley) 5/13/91
+ */
+
+/*-
+ * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the University of Utah, and William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 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.
+ *
+ * @(#)trap.c 7.4 (Berkeley) 5/13/91
+ */
+
+/*
+ * SH3 Trap and System call handling
+ *
+ * T.Horiuchi 1998.06.8
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/pool.h>
+#include <sys/user.h>
+#include <sys/kernel.h>
+#include <sys/signal.h>
+#include <sys/syscall.h>
+
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
+
+#include "systrace.h"
+#if NSYSTRACE > 0
+#include <dev/systrace.h>
+#endif
+
+#include <uvm/uvm_extern.h>
+
+#include <sh/cpu.h>
+#include <sh/mmu.h>
+#include <sh/trap.h>
+#include <sh/userret.h>
+
+#ifdef DDB
+#include <machine/db_machdep.h>
+#endif
+
+const char * const exp_type[] = {
+ "--", /* 0x000 (reset vector) */
+ "--", /* 0x020 (reset vector) */
+ "TLB miss/invalid (load)", /* 0x040 EXPEVT_TLB_MISS_LD */
+ "TLB miss/invalid (store)", /* 0x060 EXPEVT_TLB_MISS_ST */
+ "initial page write", /* 0x080 EXPEVT_TLB_MOD */
+ "TLB protection violation (load)", /* 0x0a0 EXPEVT_TLB_PROT_LD */
+ "TLB protection violation (store)", /* 0x0c0 EXPEVT_TLB_PROT_ST */
+ "address error (load)", /* 0x0e0 EXPEVT_ADDR_ERR_LD */
+ "address error (store)", /* 0x100 EXPEVT_ADDR_ERR_ST */
+ "FPU", /* 0x120 EXPEVT_FPU */
+ "--", /* 0x140 (reset vector) */
+ "unconditional trap (TRAPA)", /* 0x160 EXPEVT_TRAPA */
+ "reserved instruction code exception", /* 0x180 EXPEVT_RES_INST */
+ "illegal slot instruction exception", /* 0x1a0 EXPEVT_SLOT_INST */
+ "--", /* 0x1c0 (external interrupt) */
+ "user break point trap", /* 0x1e0 EXPEVT_BREAK */
+};
+const int exp_types = sizeof exp_type / sizeof exp_type[0];
+
+void general_exception(struct proc *, struct trapframe *, uint32_t);
+void tlb_exception(struct proc *, struct trapframe *, uint32_t);
+void ast(struct proc *, struct trapframe *);
+void syscall(struct proc *, struct trapframe *);
+
+/*
+ * void general_exception(struct proc *p, struct trapframe *tf):
+ * p ... curproc when exception occured.
+ * tf ... full user context.
+ * va ... fault va for user mode EXPEVT_ADDR_ERR_{LD,ST}
+ */
+void
+general_exception(struct proc *p, struct trapframe *tf, uint32_t va)
+{
+ int expevt = tf->tf_expevt;
+ int tra;
+ boolean_t usermode = !KERNELMODE(tf->tf_ssr);
+ union sigval sv;
+
+ uvmexp.traps++;
+
+ if (p == NULL)
+ goto do_panic;
+
+ if (usermode) {
+ KDASSERT(p->p_md.md_regs == tf); /* check exception depth */
+ expevt |= EXP_USER;
+ }
+
+ switch (expevt) {
+ case EXPEVT_TRAPA:
+ /* Check for ddb request */
+ tra = _reg_read_4(SH_(TRA));
+ if (tra == (_SH_TRA_BREAK << 2)) {
+ kdb_trap(expevt, tra, tf);
+ goto out;
+ } else
+ goto do_panic;
+ case EXPEVT_TRAPA | EXP_USER:
+ /* Check for debugger break */
+ tra = _reg_read_4(SH_(TRA));
+ switch (tra) {
+ case _SH_TRA_BREAK << 2:
+ tf->tf_spc -= 2; /* back to the breakpoint address */
+ sv.sival_ptr = (void *)tf->tf_spc;
+ trapsignal(p, SIGTRAP, expevt & ~EXP_USER, TRAP_BRKPT,
+ sv);
+ goto out;
+ case _SH_TRA_SYSCALL << 2:
+ syscall(p, tf);
+ return;
+ default:
+ sv.sival_ptr = (void *)tf->tf_spc;
+ trapsignal(p, SIGILL, expevt & ~EXP_USER, ILL_ILLTRP,
+ sv);
+ goto out;
+ }
+ break;
+
+ case EXPEVT_ADDR_ERR_LD: /* FALLTHROUGH */
+ case EXPEVT_ADDR_ERR_ST:
+ KDASSERT(p->p_md.md_pcb->pcb_onfault != NULL);
+ tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
+ if (tf->tf_spc == 0)
+ goto do_panic;
+ break;
+
+ case EXPEVT_ADDR_ERR_LD | EXP_USER: /* FALLTHROUGH */
+ case EXPEVT_ADDR_ERR_ST | EXP_USER:
+ sv.sival_ptr = (void *)va;
+ if (((int)va) < 0)
+ trapsignal(p, SIGSEGV, expevt & ~EXP_USER, SEGV_ACCERR,
+ sv);
+ else
+ trapsignal(p, SIGBUS, expevt & ~EXP_USER, BUS_ADRALN,
+ sv);
+ goto out;
+
+ case EXPEVT_RES_INST | EXP_USER: /* FALLTHROUGH */
+ case EXPEVT_SLOT_INST | EXP_USER:
+ sv.sival_ptr = (void *)tf->tf_spc;
+ trapsignal(p, SIGILL, expevt & ~EXP_USER, ILL_ILLOPC, sv);
+ goto out;
+
+ case EXPEVT_BREAK | EXP_USER:
+ sv.sival_ptr = (void *)tf->tf_spc;
+ trapsignal(p, SIGTRAP, expevt & ~EXP_USER, TRAP_TRACE, sv);
+ goto out;
+
+ default:
+ goto do_panic;
+ }
+
+ if (!usermode)
+ return;
+out:
+ userret(p);
+ return;
+
+do_panic:
+ if ((expevt >> 5) < exp_types)
+ printf("fatal %s", exp_type[expevt >> 5]);
+ else
+ printf("EXPEVT 0x%03x", expevt);
+ printf(" in %s mode\n", expevt & EXP_USER ? "user" : "kernel");
+ printf(" spc %x ssr %x \n", tf->tf_spc, tf->tf_ssr);
+
+ panic("general_exception");
+ /* NOTREACHED */
+}
+
+
+/*
+ * void tlb_exception(struct proc *p, struct trapframe *tf, uint32_t va):
+ * p ... curproc when exception occured.
+ * tf ... full user context.
+ * va ... fault address.
+ */
+void
+tlb_exception(struct proc *p, struct trapframe *tf, uint32_t va)
+{
+ struct vm_map *map;
+ pmap_t pmap;
+ union sigval sv;
+ boolean_t usermode;
+ int err, track, ftype;
+ const char *panic_msg;
+
+#define TLB_ASSERT(assert, msg) \
+ do { \
+ if (!(assert)) { \
+ panic_msg = msg; \
+ goto tlb_panic; \
+ } \
+ } while(/*CONSTCOND*/0)
+
+
+ usermode = !KERNELMODE(tf->tf_ssr);
+ if (usermode) {
+ KDASSERT(p->p_md.md_regs == tf);
+ } else {
+ KDASSERT(p == NULL || /* idle */
+ p == &proc0 || /* kthread */
+ p->p_md.md_regs != tf); /* other */
+ }
+
+ switch (tf->tf_expevt) {
+ case EXPEVT_TLB_MISS_LD:
+ track = PVH_REFERENCED;
+ ftype = VM_PROT_READ;
+ break;
+ case EXPEVT_TLB_MISS_ST:
+ track = PVH_REFERENCED;
+ ftype = VM_PROT_WRITE;
+ break;
+ case EXPEVT_TLB_MOD:
+ track = PVH_REFERENCED | PVH_MODIFIED;
+ ftype = VM_PROT_WRITE;
+ break;
+ case EXPEVT_TLB_PROT_LD:
+ TLB_ASSERT((int)va > 0,
+ "kernel virtual protection fault (load)");
+ if (usermode) {
+ sv.sival_ptr = (void *)va;
+ trapsignal(p, SIGSEGV, tf->tf_expevt, SEGV_ACCERR, sv);
+ goto user_fault;
+ } else {
+ TLB_ASSERT(p->p_md.md_pcb->pcb_onfault != NULL,
+ "no copyin/out fault handler (load protection)");
+ tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
+ }
+ return;
+
+ case EXPEVT_TLB_PROT_ST:
+ track = 0; /* call uvm_fault first. (COW) */
+ ftype = VM_PROT_WRITE;
+ break;
+
+ default:
+ TLB_ASSERT(0, "impossible expevt");
+ }
+
+ /* Select address space */
+ if (usermode) {
+ TLB_ASSERT(p != NULL, "no curproc");
+ map = &p->p_vmspace->vm_map;
+ pmap = map->pmap;
+ } else {
+ if ((int)va < 0) {
+ map = kernel_map;
+ pmap = pmap_kernel();
+ } else {
+ TLB_ASSERT(p != NULL &&
+ p->p_md.md_pcb->pcb_onfault != NULL,
+ "invalid user-space access from kernel mode");
+ if (va == 0) {
+ tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
+ return;
+ }
+ map = &p->p_vmspace->vm_map;
+ pmap = map->pmap;
+ }
+ }
+
+ /* Lookup page table. if entry found, load it. */
+ if (track && __pmap_pte_load(pmap, va, track)) {
+ if (usermode)
+ userret(p);
+ return;
+ }
+
+ /* Page not found. call fault handler */
+ if (!usermode && pmap != pmap_kernel() &&
+ p->p_md.md_pcb->pcb_faultbail) {
+ TLB_ASSERT(p->p_md.md_pcb->pcb_onfault != NULL,
+ "no copyin/out fault handler (interrupt context)");
+ tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
+ return;
+ }
+
+ err = uvm_fault(map, va, 0, ftype);
+
+ /* User stack extension */
+ if (map != kernel_map &&
+ (va >= (vaddr_t)p->p_vmspace->vm_maxsaddr) &&
+ (va < USRSTACK)) {
+ if (err == 0) {
+ struct vmspace *vm = p->p_vmspace;
+ uint32_t nss;
+ nss = btoc(USRSTACK - va);
+ if (nss > vm->vm_ssize)
+ vm->vm_ssize = nss;
+ } else if (err == EACCES) {
+ err = EFAULT;
+ }
+ }
+
+ /* Page in. load PTE to TLB. */
+ if (err == 0) {
+ boolean_t loaded = __pmap_pte_load(pmap, va, track);
+ TLB_ASSERT(loaded, "page table entry not found");
+ if (usermode)
+ userret(p);
+ return;
+ }
+
+ /* Page not found. */
+ if (usermode) {
+ sv.sival_ptr = (void *)va;
+ if (err == ENOMEM) {
+ printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
+ p->p_pid, p->p_comm,
+ p->p_cred && p->p_ucred ?
+ (int)p->p_ucred->cr_uid : -1);
+ trapsignal(p, SIGKILL, tf->tf_expevt, SEGV_MAPERR, sv);
+ } else
+ trapsignal(p, SIGSEGV, tf->tf_expevt, SEGV_MAPERR, sv);
+ goto user_fault;
+ } else {
+ TLB_ASSERT(p->p_md.md_pcb->pcb_onfault,
+ "no copyin/out fault handler (page not found)");
+ tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
+ }
+ return;
+
+user_fault:
+ userret(p);
+ ast(p, tf);
+ return;
+
+tlb_panic:
+ panic("tlb_exception: %s\n"
+ "expevt=%x va=%08x ssr=%08x spc=%08x proc=%p onfault=%p",
+ panic_msg, tf->tf_expevt, va, tf->tf_ssr, tf->tf_spc,
+ p, p ? p->p_md.md_pcb->pcb_onfault : NULL);
+#undef TLB_ASSERT
+}
+
+
+/*
+ * void ast(struct proc *p, struct trapframe *tf):
+ * p ... curproc when exception occured.
+ * tf ... full user context.
+ * This is called upon exception return. if return from kernel to user,
+ * handle asynchronous software traps and context switch if needed.
+ */
+void
+ast(struct proc *p, struct trapframe *tf)
+{
+ if (KERNELMODE(tf->tf_ssr))
+ return;
+ KDASSERT(p != NULL);
+ KDASSERT(p->p_md.md_regs == tf);
+
+ while (p->p_md.md_astpending) {
+ uvmexp.softs++;
+ p->p_md.md_astpending = 0;
+
+ if (p->p_flag & P_OWEUPC) {
+ p->p_flag &= ~P_OWEUPC;
+ ADDUPROF(p);
+ }
+
+ if (want_resched) {
+ /* We are being preempted. */
+ preempt(NULL);
+ }
+
+ userret(p);
+ }
+}
+
+void
+syscall(struct proc *p, struct trapframe *tf)
+{
+ caddr_t params;
+ const struct sysent *callp;
+ int error, oerror, opc, nsys;
+ size_t argsize;
+ register_t code, args[8], rval[2], ocode;
+
+ uvmexp.syscalls++;
+
+ opc = tf->tf_spc;
+ ocode = code = tf->tf_r0;
+
+ nsys = p->p_emul->e_nsysent;
+ callp = p->p_emul->e_sysent;
+
+ params = (caddr_t)tf->tf_r15;
+
+ switch (code) {
+ case SYS_syscall:
+ /*
+ * Code is first argument, followed by actual args.
+ */
+ code = tf->tf_r4;
+ break;
+ case SYS___syscall:
+ /*
+ * Like syscall, but code is a quad, so as to maintain
+ * quad alignment for the rest of the arguments.
+ */
+ if (callp != sysent)
+ break;
+#if _BYTE_ORDER == BIG_ENDIAN
+ code = tf->tf_r5;
+#else
+ code = tf->tf_r4;
+#endif
+ break;
+ default:
+ break;
+ }
+ if (code < 0 || code >= nsys)
+ callp += p->p_emul->e_nosys; /* illegal */
+ else
+ callp += code;
+ argsize = callp->sy_argsize;
+#ifdef DIAGNOSTIC
+ if (argsize > sizeof args) {
+ callp += p->p_emul->e_nosys - code;
+ goto bad;
+ }
+#endif
+
+ switch (ocode) {
+ case SYS_syscall:
+ if (argsize) {
+ args[0] = tf->tf_r5;
+ args[1] = tf->tf_r6;
+ args[2] = tf->tf_r7;
+ if (argsize > 3 * sizeof(int)) {
+ argsize -= 3 * sizeof(int);
+ error = copyin(params, (caddr_t)&args[3],
+ argsize);
+ } else
+ error = 0;
+ } else
+ error = 0;
+ break;
+ case SYS___syscall:
+ if (argsize) {
+ args[0] = tf->tf_r6;
+ args[1] = tf->tf_r7;
+ if (argsize > 2 * sizeof(int)) {
+ argsize -= 2 * sizeof(int);
+ error = copyin(params, (caddr_t)&args[2],
+ argsize);
+ } else
+ error = 0;
+ } else
+ error = 0;
+ break;
+ default:
+ if (argsize) {
+ args[0] = tf->tf_r4;
+ args[1] = tf->tf_r5;
+ args[2] = tf->tf_r6;
+ args[3] = tf->tf_r7;
+ if (argsize > 4 * sizeof(int)) {
+ argsize -= 4 * sizeof(int);
+ error = copyin(params, (caddr_t)&args[4],
+ argsize);
+ } else
+ error = 0;
+ } else
+ error = 0;
+ break;
+ }
+
+ if (error)
+ goto bad;
+
+#ifdef SYSCALL_DEBUG
+ scdebug_call(p, code, args);
+#endif
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSCALL))
+ ktrsyscall(p, code, callp->sy_argsize, args);
+#endif
+
+ rval[0] = 0;
+ rval[1] = tf->tf_r1;
+#if NSYSTRACE > 0
+ if (ISSET(p->p_flag, P_SYSTRACE))
+ error = systrace_redirect(code, p, args, rval);
+ else
+#endif
+ error = (*callp->sy_call)(p, args, rval);
+
+ switch (oerror = error) {
+ case 0:
+ tf->tf_r0 = rval[0];
+ tf->tf_r1 = rval[1];
+ tf->tf_ssr |= PSL_TBIT; /* T bit */
+ break;
+ case ERESTART:
+ /* 2 = TRAPA instruction size */
+ tf->tf_spc = opc - 2;
+ break;
+ case EJUSTRETURN:
+ /* nothing to do */
+ break;
+ default:
+bad:
+ if (p->p_emul->e_errno)
+ error = p->p_emul->e_errno[error];
+ tf->tf_r0 = error;
+ tf->tf_ssr &= ~PSL_TBIT; /* T bit */
+ break;
+ }
+
+#ifdef SYSCALL_DEBUG
+ scdebug_ret(p, code, oerror, rval);
+#endif
+ userret(p);
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSRET))
+ ktrsysret(p, code, oerror, rval[0]);
+#endif
+}
+
+/*
+ * void child_return(void *arg):
+ *
+ * uvm_fork sets this routine to proc_trampoline's service function.
+ * when returning from here, jump to userland.
+ */
+void
+child_return(void *arg)
+{
+ struct proc *p = arg;
+ struct trapframe *tf = p->p_md.md_regs;
+
+ tf->tf_r0 = 0;
+ tf->tf_ssr |= PSL_TBIT; /* This indicates no error. */
+
+ userret(p);
+
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSRET))
+ ktrsysret(p,
+ (p->p_flag & P_PPWAIT) ? SYS_vfork : SYS_fork, 0, 0);
+#endif
+}
+
diff --git a/sys/arch/sh/sh/vectors.S b/sys/arch/sh/sh/vectors.S
new file mode 100644
index 00000000000..26c7d1d235e
--- /dev/null
+++ b/sys/arch/sh/sh/vectors.S
@@ -0,0 +1,275 @@
+/* $OpenBSD: vectors.S,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: exception_vector.S,v 1.19 2006/08/22 21:47:57 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ */
+
+#include "assym.h"
+
+#include <sh/param.h>
+#include <sh/asm.h>
+#include <sh/locore.h>
+#include <sh/trap.h>
+#include <sh/ubcreg.h>
+#include <sh/mmu_sh3.h>
+#include <sh/mmu_sh4.h>
+
+/*
+ * Exception vectors. The following routines are copied to vector addreses.
+ * sh_vector_generic: VBR + 0x100
+ * sh_vector_tlbmiss: VBR + 0x400
+ * sh_vector_interrupt: VBR + 0x600
+ */
+
+#define VECTOR_END_MARKER(sym) \
+ .globl _C_LABEL(sym); \
+ _C_LABEL(sym):
+
+
+/*
+ * LINTSTUB: Var: char sh_vector_generic[1];
+ *
+ * void sh_vector_generic(void) __attribute__((__noreturn__))
+ * Copied to VBR+0x100. This code should be position independent
+ * and no more than 786 bytes long (== 0x400 - 0x100).
+ */
+NENTRY(sh_vector_generic)
+ __EXCEPTION_ENTRY
+ __INTR_MASK(r0, r1)
+ /* Identify exception cause */
+ MOV (EXPEVT, r0)
+ mov.l @r0, r0
+ mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
+ /* Get curproc */
+ mov.l _L.curproc, r1
+ mov.l @r1, r4 /* 1st arg */
+ /* Get TEA */
+ MOV (TEA, r1)
+ mov.l @r1, r6 /* 3rd arg */
+ /* Check TLB exception or not */
+ mov.l _L.TLB_PROT_ST, r1
+ cmp/hi r1, r0
+ bt 1f
+
+ /* tlb_exception(curproc, trapframe, trunc_page(TEA)); */
+ mov.l _L.VPN_MASK, r1
+ and r1, r6 /* va = trunc_page(va) */
+ __EXCEPTION_UNBLOCK(r0, r1)
+ mov.l _L.tlb, r0
+ jsr @r0
+ mov r14, r5 /* 2nd arg */
+ bra 2f
+ nop
+
+ /* general_exception(curproc, trapframe, TEA); */
+1: mov r4, r8
+#ifdef DDB
+ mov #0, r2
+ MOV (BBRA, r1)
+ mov.w r2, @r1 /* disable UBC */
+ mov.l r2, @(TF_UBC, r14) /* clear trapframe->tf_ubc */
+#endif /* DDB */
+ __EXCEPTION_UNBLOCK(r0, r1)
+ mov.l _L.general, r0
+ jsr @r0
+ mov r14, r5 /* 2nd arg */
+
+ /* Check for ASTs on exit to user mode. */
+ mov r8, r4
+ mov.l _L.ast, r0
+ jsr @r0
+ mov r14, r5
+#ifdef DDB /* BBRA = trapframe->tf_ubc */
+ __EXCEPTION_BLOCK(r0, r1)
+ mov.l @(TF_UBC, r14), r0
+ MOV (BBRA, r1)
+ mov.w r0, @r1
+#endif /* DDB */
+2: __EXCEPTION_RETURN
+ /* NOTREACHED */
+ .align 2
+_L.curproc: .long _C_LABEL(curproc)
+REG_SYMBOL(EXPEVT)
+REG_SYMBOL(BBRA)
+REG_SYMBOL(TEA)
+_L.tlb: .long _C_LABEL(tlb_exception)
+_L.general: .long _C_LABEL(general_exception)
+_L.ast: .long _C_LABEL(ast)
+_L.TLB_PROT_ST: .long 0xc0
+_L.VPN_MASK: .long 0xfffff000
+
+/* LINTSTUB: Var: char sh_vector_generic_end[1]; */
+VECTOR_END_MARKER(sh_vector_generic_end)
+ SET_ENTRY_SIZE(sh_vector_generic)
+
+
+#ifdef SH3
+/*
+ * LINTSTUB: Var: char sh3_vector_tlbmiss[1];
+ *
+ * void sh3_vector_tlbmiss(void) __attribute__((__noreturn__))
+ * Copied to VBR+0x400. This code should be position independent
+ * and no more than 512 bytes long (== 0x600 - 0x400).
+ */
+NENTRY(sh3_vector_tlbmiss)
+ __EXCEPTION_ENTRY
+ mov #(SH3_TEA & 0xff), r0
+ mov.l @r0, r6 /* 3rd arg: va = TEA */
+#if !defined(P1_STACK)
+ /* Load kernel stack */
+ mov.l __L.VPN_MASK, r0
+ and r6, r0
+ tst r0, r0 /* check VPN == 0 */
+ bt 6f
+ mov.l _L.CURUPTE, r1
+ mov.l @r1, r1
+ mov #UPAGES,r3
+ mov #1, r2
+4: mov.l @r1+, r7
+ cmp/eq r7, r0 /* md_upte.addr: u-area VPN */
+ bt 5f
+ add #4, r1 /* skip md_upte.data */
+ cmp/eq r2, r3
+ bf/s 4b
+ add #1, r2
+ bra 7f /* pull insn at 6f into delay slot */
+ mov #(SH3_EXPEVT & 0xff), r0
+5: mov.l @r1, r2 /* md_upte.data: u-area PTE */
+ mov #(SH3_PTEL & 0xff), r1
+ mov.l r2, @r1
+ mov #(SH3_PTEH & 0xff), r1
+ mov.l @r1, r2
+ mov.l __L.VPN_MASK, r0
+ and r2, r0
+ mov.l r0, @r1 /* ASID 0 */
+ ldtlb
+ bra 3f
+ mov.l r2, @r1 /* restore ASID */
+#endif /* !P1_STACK */
+6: mov #(SH3_EXPEVT & 0xff), r0
+7: mov.l @r0, r0
+ mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
+ mov.l 2f, r0
+ mov.l @r0, r4 /* 1st arg */
+ __INTR_MASK(r0, r1)
+ __EXCEPTION_UNBLOCK(r0, r1)
+ mov.l 1f, r0
+ jsr @r0
+ mov r14, r5 /* 2nd arg */
+3: __EXCEPTION_RETURN
+ .align 2
+2: .long _C_LABEL(curproc)
+1: .long _C_LABEL(tlb_exception)
+__L.VPN_MASK: .long 0xfffff000
+_L.CURUPTE: .long _C_LABEL(curupte)
+
+/* LINTSTUB: Var: char sh3_vector_tlbmiss_end[1]; */
+VECTOR_END_MARKER(sh3_vector_tlbmiss_end)
+ SET_ENTRY_SIZE(sh3_vector_tlbmiss)
+#endif /* SH3 */
+
+
+#ifdef SH4
+/*
+ * LINTSTUB: Var: char sh4_vector_tlbmiss[1];
+ *
+ * void sh4_vector_tlbmiss(void) __attribute__((__noreturn__))
+ * Copied to VBR+0x400. This code should be position independent
+ * and no more than 512 bytes long (== 0x600 - 0x400).
+ */
+NENTRY(sh4_vector_tlbmiss)
+ __EXCEPTION_ENTRY
+ mov.l _L.TEA4, r0
+ mov.l @r0, r6
+ mov.l _L.EXPEVT4, r0
+ mov.l @r0, r0
+ mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
+ mov.l 2f, r0
+ mov.l @r0, r4 /* 1st arg */
+ __INTR_MASK(r0, r1)
+ __EXCEPTION_UNBLOCK(r0, r1)
+ mov.l 1f, r0
+ jsr @r0
+ mov r14, r5 /* 2nd arg */
+ __EXCEPTION_RETURN
+ .align 2
+1: .long _C_LABEL(tlb_exception)
+2: .long _C_LABEL(curproc)
+_L.EXPEVT4: .long SH4_EXPEVT
+_L.TEA4: .long SH4_TEA
+
+/* LINTSTUB: Var: char sh4_vector_tlbmiss_end[1]; */
+VECTOR_END_MARKER(sh4_vector_tlbmiss_end)
+ SET_ENTRY_SIZE(sh4_vector_tlbmiss)
+#endif /* SH4 */
+
+
+/*
+ * LINTSTUB: Var: char sh_vector_interrupt[1];
+ *
+ * void sh_vector_interrupt(void) __attribute__((__noreturn__)):
+ * copied to VBR+0x600. This code should be relocatable.
+ */
+NENTRY(sh_vector_interrupt)
+ __EXCEPTION_ENTRY
+ xor r0, r0
+ mov.l r0, @(TF_EXPEVT, r14) /* (for debug) */
+ stc r0_bank,r6 /* ssp */
+ /* Enable exception for P3 access */
+ __INTR_MASK(r0, r1)
+ __EXCEPTION_UNBLOCK(r0, r1)
+ /* uvmexp.intrs++ */
+ mov.l __L.uvmexp.intrs, r0
+ mov.l @r0, r1
+ add #1 r1
+ mov.l r1, @r0
+ /* Dispatch interrupt handler */
+ mov.l __L.intc_intr, r0
+ jsr @r0 /* intc_intr(ssr, spc, ssp) */
+ nop
+ /* Check for ASTs on exit to user mode. */
+ mov.l 1f, r0
+ mov.l @r0, r4 /* 1st arg */
+ mov.l __L.ast, r0
+ jsr @r0
+ mov r14, r5 /* 2nd arg */
+ __EXCEPTION_RETURN
+ .align 2
+1: .long _C_LABEL(curproc)
+__L.intc_intr: .long _C_LABEL(intc_intr)
+__L.ast: .long _C_LABEL(ast)
+__L.uvmexp.intrs: .long _C_LABEL(uvmexp) + UVMEXP_INTRS
+
+/* LINTSTUB: Var: char sh_vector_interrupt_end[1]; */
+VECTOR_END_MARKER(sh_vector_interrupt_end)
+ SET_ENTRY_SIZE(sh_vector_interrupt)
diff --git a/sys/arch/sh/sh/vm_machdep.c b/sys/arch/sh/sh/vm_machdep.c
new file mode 100644
index 00000000000..20bb7adc942
--- /dev/null
+++ b/sys/arch/sh/sh/vm_machdep.c
@@ -0,0 +1,364 @@
+/* $OpenBSD: vm_machdep.c,v 1.1 2006/10/06 21:02:55 miod Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.53 2006/08/31 16:49:21 matt Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
+ * Copyright (c) 1982, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department, and William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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.
+ *
+ * @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
+ */
+
+/*-
+ * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
+ * Copyright (c) 1989, 1990 William Jolitz
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department, and William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 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.
+ *
+ * @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
+ */
+
+/*
+ * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/malloc.h>
+#include <sys/vnode.h>
+#include <sys/buf.h>
+#include <sys/user.h>
+#include <sys/core.h>
+#include <sys/exec.h>
+#include <sys/ptrace.h>
+#include <sys/signalvar.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <sh/locore.h>
+#include <sh/cpu.h>
+#include <sh/reg.h>
+#include <sh/mmu.h>
+#include <sh/cache.h>
+
+extern void proc_trampoline(void);
+
+/*
+ * Finish a fork operation, with process p2 nearly set up.
+ * Copy and update the pcb and trap frame, making the child ready to run.
+ *
+ * Rig the child's kernel stack so that it will start out in
+ * proc_trampoline() and call child_return() with p2 as an
+ * argument. This causes the newly-created child process to go
+ * directly to user level with an apparent return value of 0 from
+ * fork(), while the parent process returns normally.
+ *
+ * p1 is the process being forked; if p1 == &proc0, we are creating
+ * a kernel thread, and the return path and argument are specified with
+ * `func' and `arg'.
+ *
+ * If an alternate user-level stack is requested (with non-zero values
+ * in both the stack and stacksize args), set up the user stack pointer
+ * accordingly.
+ */
+void
+cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize,
+ void (*func)(void *), void *arg)
+{
+ struct pcb *pcb;
+ struct trapframe *tf;
+ struct switchframe *sf;
+ vaddr_t spbase, fptop;
+#define P1ADDR(x) (SH3_PHYS_TO_P1SEG(*__pmap_kpte_lookup(x) & PG_PPN))
+
+ KDASSERT(p1 == curproc || p1 == &proc0);
+
+ /* Copy flags */
+ p2->p_md.md_flags = p1->p_md.md_flags;
+
+ pcb = NULL; /* XXXGCC: -Wuninitialized */
+#ifdef SH3
+ /*
+ * Convert frame pointer top to P1. because SH3 can't make
+ * wired TLB entry, context store space accessing must not cause
+ * exception. For SH3, we are 4K page, P3/P1 conversion don't
+ * cause virtual-aliasing.
+ */
+ if (CPU_IS_SH3)
+ pcb = (struct pcb *)P1ADDR((vaddr_t)&p2->p_addr->u_pcb);
+#endif /* SH3 */
+#ifdef SH4
+ /* SH4 can make wired entry, no need to convert to P1. */
+ if (CPU_IS_SH4)
+ pcb = &p2->p_addr->u_pcb;
+#endif /* SH4 */
+
+ p2->p_md.md_pcb = pcb;
+ fptop = (vaddr_t)pcb + PAGE_SIZE;
+
+ /* set up the kernel stack pointer */
+ spbase = (vaddr_t)p2->p_addr + PAGE_SIZE;
+#ifdef P1_STACK
+ /* Convert to P1 from P3 */
+ /*
+ * wbinv u-area to avoid cache-aliasing, since kernel stack
+ * is accessed from P1 instead of P3.
+ */
+ if (SH_HAS_VIRTUAL_ALIAS)
+ sh_dcache_wbinv_range((vaddr_t)p2->p_addr, USPACE);
+ spbase = P1ADDR(spbase);
+#else /* !P1_STACK */
+ /* Prepare u-area PTEs */
+#ifdef SH3
+ if (CPU_IS_SH3)
+ sh3_switch_setup(p2);
+#endif
+#ifdef SH4
+ if (CPU_IS_SH4)
+ sh4_switch_setup(p2);
+#endif
+#endif /* !P1_STACK */
+
+#ifdef KSTACK_DEBUG
+ /* Fill magic number for tracking */
+ memset((char *)fptop - PAGE_SIZE + sizeof(struct user), 0x5a,
+ PAGE_SIZE - sizeof(struct user));
+ memset((char *)spbase, 0xa5, (USPACE - PAGE_SIZE));
+ memset(&pcb->pcb_sf, 0xb4, sizeof(struct switchframe));
+#endif /* KSTACK_DEBUG */
+
+ /*
+ * Copy the user context.
+ */
+ p2->p_md.md_regs = tf = (struct trapframe *)fptop - 1;
+ memcpy(tf, p1->p_md.md_regs, sizeof(struct trapframe));
+
+ /*
+ * If specified, give the child a different stack.
+ */
+ if (stack != NULL)
+ tf->tf_r15 = (u_int)stack + stacksize;
+
+ /* Setup switch frame */
+ sf = &pcb->pcb_sf;
+ sf->sf_r11 = (int)arg; /* proc_trampoline hook func */
+ sf->sf_r12 = (int)func; /* proc_trampoline hook func's arg */
+ sf->sf_r15 = spbase + USPACE - PAGE_SIZE;/* current stack pointer */
+ sf->sf_r7_bank = sf->sf_r15; /* stack top */
+ sf->sf_r6_bank = (vaddr_t)tf; /* current frame pointer */
+ /* when switch to me, jump to proc_trampoline */
+ sf->sf_pr = (int)proc_trampoline;
+ /*
+ * Enable interrupt when switch frame is restored, since
+ * kernel thread begin to run without restoring trapframe.
+ */
+ sf->sf_sr = PSL_MD; /* kernel mode, interrupt enable */
+}
+
+/*
+ * Dump the machine specific segment at the start of a core dump.
+ */
+struct md_core {
+ struct reg intreg;
+};
+
+int
+cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred,
+ struct core *chdr)
+{
+ struct md_core md_core;
+ struct coreseg cseg;
+ int error;
+
+ CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0);
+ chdr->c_hdrsize = ALIGN(sizeof(*chdr));
+ chdr->c_seghdrsize = ALIGN(sizeof(cseg));
+ chdr->c_cpusize = sizeof(md_core);
+
+ /* Save integer registers. */
+ error = process_read_regs(p, &md_core.intreg);
+ if (error)
+ return error;
+
+ CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
+ cseg.c_addr = 0;
+ cseg.c_size = chdr->c_cpusize;
+
+ error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
+ (off_t)chdr->c_hdrsize, UIO_SYSSPACE, IO_NODELOCKED | IO_UNIT, cred,
+ NULL, p);
+ if (error)
+ return error;
+
+ error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof(md_core),
+ (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
+ IO_NODELOCKED | IO_UNIT, cred, NULL, p);
+ if (error)
+ return error;
+
+ chdr->c_nseg++;
+ return 0;
+}
+
+/*
+ * Move pages from one kernel virtual address to another.
+ * Both addresses are assumed to reside in the Sysmap,
+ * and size must be a multiple of PAGE_SIZE.
+ */
+
+void
+pagemove(caddr_t from, caddr_t to, size_t size)
+{
+ paddr_t pa;
+ boolean_t rv;
+
+#ifdef DEBUG
+ if (size % PAGE_SIZE)
+ panic("pagemove: size=%08lx", (u_long) size);
+#endif
+
+ while (size > 0) {
+ rv = pmap_extract(pmap_kernel(), (vaddr_t) from, &pa);
+#ifdef DEBUG
+ if (rv == FALSE)
+ panic("pagemove 2");
+ if (pmap_extract(pmap_kernel(), (vaddr_t) to, NULL) == TRUE)
+ panic("pagemove 3");
+#endif
+ pmap_kremove((vaddr_t) from, PAGE_SIZE);
+ pmap_kenter_pa((vaddr_t) to, pa, VM_PROT_READ|VM_PROT_WRITE);
+ from += PAGE_SIZE;
+ to += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+ pmap_update(pmap_kernel());
+}
+
+/*
+ * Map an IO request into kernel virtual address space.
+ * All requests are (re)mapped into kernel VA space via the phys_map
+ * (a name with only slightly more meaning than "kernel_map")
+ */
+
+void
+vmapbuf(struct buf *bp, vsize_t len)
+{
+ vaddr_t faddr, taddr, off;
+ paddr_t fpa;
+ pmap_t kpmap, upmap;
+
+ if ((bp->b_flags & B_PHYS) == 0)
+ panic("vmapbuf");
+ bp->b_saveaddr = bp->b_data;
+ faddr = trunc_page((vaddr_t)bp->b_data);
+ off = (vaddr_t)bp->b_data - faddr;
+ len = round_page(off + len);
+ taddr = uvm_km_valloc_wait(phys_map, len);
+ bp->b_data = (caddr_t)(taddr + off);
+ /*
+ * The region is locked, so we expect that pmap_pte() will return
+ * non-NULL.
+ * XXX: unwise to expect this in a multithreaded environment.
+ * anything can happen to a pmap between the time we lock a
+ * region, release the pmap lock, and then relock it for
+ * the pmap_extract().
+ *
+ * no need to flush TLB since we expect nothing to be mapped
+ * where we we just allocated (TLB will be flushed when our
+ * mapping is removed).
+ */
+ upmap = vm_map_pmap(&bp->b_proc->p_vmspace->vm_map);
+ kpmap = vm_map_pmap(phys_map);
+ while (len) {
+ pmap_extract(upmap, faddr, &fpa);
+ pmap_enter(kpmap, taddr, fpa,
+ VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED);
+ faddr += PAGE_SIZE;
+ taddr += PAGE_SIZE;
+ len -= PAGE_SIZE;
+ }
+ pmap_update(kpmap);
+}
+
+/*
+ * Free the io map PTEs associated with this IO operation.
+ * We also invalidate the TLB entries and restore the original b_addr.
+ */
+void
+vunmapbuf(struct buf *bp, vsize_t len)
+{
+ vaddr_t addr, off;
+ pmap_t kpmap;
+
+ if ((bp->b_flags & B_PHYS) == 0)
+ panic("vunmapbuf");
+ addr = trunc_page((vaddr_t)bp->b_data);
+ off = (vaddr_t)bp->b_data - addr;
+ len = round_page(off + len);
+ kpmap = vm_map_pmap(phys_map);
+ pmap_remove(kpmap, addr, addr + len);
+ pmap_update(kpmap);
+ uvm_km_free_wakeup(phys_map, addr, len);
+ bp->b_data = bp->b_saveaddr;
+ bp->b_saveaddr = 0;
+}