summaryrefslogtreecommitdiff
path: root/sys/arch/sh/dev
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/arch/sh/dev
parentb50063e7723d8a96f3eaeb641e59f7f161dcd917 (diff)
Preliminary bits for SuperH-based ports, based on NetBSD/sh3 codebase with
minor changes.
Diffstat (limited to 'sys/arch/sh/dev')
-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
7 files changed, 3242 insertions, 0 deletions
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);