summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2010-01-09 18:29:35 +0000
committerimp <imp@FreeBSD.org>2010-01-09 18:29:35 +0000
commit0b43e837d8877c9f0761703916c6e7962781ae15 (patch)
tree4ffd33141343a20974b25feab74ad54407adb0f4
parent3446c70b2d867010cf85621920fa1a431cf4a387 (diff)
parent75f6d17b0e6c09d65b88078c4f9eb12e4e637651 (diff)
downloadFreeBSD-src-0b43e837d8877c9f0761703916c6e7962781ae15.zip
FreeBSD-src-0b43e837d8877c9f0761703916c6e7962781ae15.tar.gz
Merge from projects/mips to head by hand:
Copy over the support files (except sys/conf and sys/mips/conf) for RMI XLR processor support. This port has been contributed by RMI and brought up to date by Randal Stewart (rrs@). This port is a work in progress, and there might still be significant changes. The port makes it to multi-user, but is still early beta.
-rw-r--r--sys/mips/rmi/Makefile.msgring14
-rw-r--r--sys/mips/rmi/board.c180
-rw-r--r--sys/mips/rmi/board.h282
-rw-r--r--sys/mips/rmi/bus_space_rmi.c831
-rw-r--r--sys/mips/rmi/clock.c346
-rw-r--r--sys/mips/rmi/clock.h41
-rwxr-xr-xsys/mips/rmi/debug.h103
-rw-r--r--sys/mips/rmi/ehcireg.h309
-rw-r--r--sys/mips/rmi/ehcivar.h195
-rw-r--r--sys/mips/rmi/files.xlr26
-rw-r--r--sys/mips/rmi/interrupt.h42
-rw-r--r--sys/mips/rmi/intr_machdep.c217
-rw-r--r--sys/mips/rmi/iodi.c308
-rw-r--r--sys/mips/rmi/iomap.h113
-rw-r--r--sys/mips/rmi/msgring.c317
-rw-r--r--sys/mips/rmi/msgring.cfg1182
-rwxr-xr-xsys/mips/rmi/msgring.h529
-rw-r--r--sys/mips/rmi/msgring_xls.c217
-rwxr-xr-xsys/mips/rmi/msgring_xls.cfg563
-rw-r--r--sys/mips/rmi/on_chip.c330
-rw-r--r--sys/mips/rmi/pcibus.c357
-rw-r--r--sys/mips/rmi/pcibus.h62
-rw-r--r--sys/mips/rmi/perfmon.h183
-rw-r--r--sys/mips/rmi/perfmon_kern.c163
-rw-r--r--sys/mips/rmi/perfmon_percpu.c342
-rw-r--r--sys/mips/rmi/perfmon_utils.h126
-rw-r--r--sys/mips/rmi/perfmon_xlrconfig.h156
-rw-r--r--sys/mips/rmi/pic.h279
-rw-r--r--sys/mips/rmi/rmi_mips_exts.h144
-rw-r--r--sys/mips/rmi/rootfs_list.txt676
-rwxr-xr-xsys/mips/rmi/shared_structs.h110
-rwxr-xr-xsys/mips/rmi/shared_structs_func.h54
-rwxr-xr-xsys/mips/rmi/shared_structs_offsets.h76
-rw-r--r--sys/mips/rmi/std.xlr10
-rw-r--r--sys/mips/rmi/tick.c113
-rw-r--r--sys/mips/rmi/uart_bus_xlr_iodi.c80
-rw-r--r--sys/mips/rmi/uart_cpu_mips_xlr.c84
-rw-r--r--sys/mips/rmi/xlr_boot1_console.c113
-rw-r--r--sys/mips/rmi/xlr_csum_nocopy.S217
-rw-r--r--sys/mips/rmi/xlr_i2c.c455
-rw-r--r--sys/mips/rmi/xlr_machdep.c726
-rw-r--r--sys/mips/rmi/xlr_pci.c426
-rw-r--r--sys/mips/rmi/xlrconfig.h336
-rw-r--r--sys/mips/rmi/xls_ehci.c303
44 files changed, 11736 insertions, 0 deletions
diff --git a/sys/mips/rmi/Makefile.msgring b/sys/mips/rmi/Makefile.msgring
new file mode 100644
index 0000000..d04978e
--- /dev/null
+++ b/sys/mips/rmi/Makefile.msgring
@@ -0,0 +1,14 @@
+RM = rm
+MSGRNG_CFG = msgring.cfg
+
+MSGRNG_CFG_C = $(patsubst %.cfg,%.c,$(MSGRNG_CFG))
+
+#all: msgring.l msgring.y msgring.cfg
+all: $(MSGRNG_CFG)
+ flex -omsgring.lex.c msgring.l
+ bison -d -omsgring.yacc.c msgring.y
+ gcc -g3 msgring.lex.c msgring.yacc.c -o msgring
+ ./msgring -i $(MSGRNG_CFG) -o $(MSGRNG_CFG_C)
+
+clean:
+ $(RM) -f msgring.lex.c msgring.yacc.c msgring.yacc.h msgring msgring.o*
diff --git a/sys/mips/rmi/board.c b/sys/mips/rmi/board.c
new file mode 100644
index 0000000..932fee2
--- /dev/null
+++ b/sys/mips/rmi/board.c
@@ -0,0 +1,180 @@
+/*********************************************************************
+ *
+ * Copyright 2003-2006 Raza Microelectronics, Inc. (RMI). 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 Raza Microelectronics, Inc. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RMI OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************RMI_2**********************************/
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <machine/cpufunc.h>
+#include <mips/rmi/msgring.h>
+#include <mips/rmi/board.h>
+#include <mips/rmi/pic.h>
+#include <mips/rmi/shared_structs.h>
+
+static int xlr_rxstn_to_txstn_map[128] = {
+ [0 ... 7] = TX_STN_CPU_0,
+ [8 ... 15] = TX_STN_CPU_1,
+ [16 ... 23] = TX_STN_CPU_2,
+ [24 ... 31] = TX_STN_CPU_3,
+ [32 ... 39] = TX_STN_CPU_4,
+ [40 ... 47] = TX_STN_CPU_5,
+ [48 ... 55] = TX_STN_CPU_6,
+ [56 ... 63] = TX_STN_CPU_7,
+ [64 ... 95] = TX_STN_INVALID,
+ [96 ... 103] = TX_STN_GMAC,
+ [104 ... 107] = TX_STN_DMA,
+ [108 ... 111] = TX_STN_INVALID,
+ [112 ... 113] = TX_STN_XGS_0,
+ [114 ... 115] = TX_STN_XGS_1,
+ [116 ... 119] = TX_STN_INVALID,
+ [120 ... 127] = TX_STN_SAE
+};
+
+static int xls_rxstn_to_txstn_map[128] = {
+ [0 ... 7] = TX_STN_CPU_0,
+ [8 ... 15] = TX_STN_CPU_1,
+ [16 ... 23] = TX_STN_CPU_2,
+ [24 ... 31] = TX_STN_CPU_3,
+ [32 ... 63] = TX_STN_INVALID,
+ [64 ... 71] = TX_STN_PCIE,
+ [72 ... 79] = TX_STN_INVALID,
+ [80 ... 87] = TX_STN_GMAC1,
+ [88 ... 95] = TX_STN_INVALID,
+ [96 ... 103] = TX_STN_GMAC0,
+ [104 ... 107] = TX_STN_DMA,
+ [108 ... 111] = TX_STN_CDE,
+ [112 ... 119] = TX_STN_INVALID,
+ [120 ... 127] = TX_STN_SAE
+};
+
+struct stn_cc *xlr_core_cc_configs[] = {&cc_table_cpu_0, &cc_table_cpu_1,
+ &cc_table_cpu_2, &cc_table_cpu_3,
+ &cc_table_cpu_4, &cc_table_cpu_5,
+&cc_table_cpu_6, &cc_table_cpu_7};
+
+struct stn_cc *xls_core_cc_configs[] = {&xls_cc_table_cpu_0, &xls_cc_table_cpu_1,
+&xls_cc_table_cpu_2, &xls_cc_table_cpu_3};
+
+struct xlr_board_info xlr_board_info;
+
+/*
+ * All our knowledge of chip and board that cannot be detected by probing
+ * at run-time goes here
+ */
+int
+xlr_board_info_setup()
+{
+ if (xlr_is_xls()) {
+ xlr_board_info.is_xls = 1;
+ xlr_board_info.nr_cpus = 8;
+ xlr_board_info.usb = 1;
+ xlr_board_info.cfi =
+ (xlr_boot1_info.board_major_version != RMI_XLR_BOARD_ARIZONA_VIII);
+ xlr_board_info.pci_irq = 0;
+ xlr_board_info.credit_configs = xls_core_cc_configs;
+ xlr_board_info.bucket_sizes = &xls_bucket_sizes;
+ xlr_board_info.msgmap = xls_rxstn_to_txstn_map;
+ xlr_board_info.gmacports = 8;
+
+ /* network block 0 */
+ xlr_board_info.gmac_block[0].type = XLR_GMAC;
+ xlr_board_info.gmac_block[0].enabled = 0xf;
+ xlr_board_info.gmac_block[0].credit_config = &xls_cc_table_gmac0;
+ xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0;
+ xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0;
+ if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI)
+ xlr_board_info.gmac_block[0].mode = XLR_PORT0_RGMII;
+ else
+ xlr_board_info.gmac_block[0].mode = XLR_SGMII;
+ xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET;
+ xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ;
+ xlr_board_info.gmac_block[0].baseinst = 0;
+
+ /* network block 1 */
+ xlr_board_info.gmac_block[1].type = XLR_GMAC;
+ xlr_board_info.gmac_block[1].enabled = 0xf;
+ xlr_board_info.gmac_block[1].credit_config = &xls_cc_table_gmac1;
+ xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_GMAC1_TX0;
+ xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_GMAC1_FR_0;
+ xlr_board_info.gmac_block[1].mode = XLR_SGMII;
+ xlr_board_info.gmac_block[1].baseaddr = XLR_IO_GMAC_4_OFFSET;
+ xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ;
+ xlr_board_info.gmac_block[1].baseinst = 4;
+
+ /* network block 2 */
+ xlr_board_info.gmac_block[2].enabled = 0; /* disabled on XLS */
+ } else {
+ xlr_board_info.is_xls = 0;
+ xlr_board_info.nr_cpus = 32;
+ xlr_board_info.usb = 0;
+ xlr_board_info.cfi = 1;
+ xlr_board_info.pci_irq = 0;
+ xlr_board_info.credit_configs = xlr_core_cc_configs;
+ xlr_board_info.bucket_sizes = &bucket_sizes;
+ xlr_board_info.msgmap = xlr_rxstn_to_txstn_map;
+ xlr_board_info.gmacports = 4;
+
+ /* GMAC0 */
+ xlr_board_info.gmac_block[0].type = XLR_GMAC;
+ xlr_board_info.gmac_block[0].enabled = 0xf;
+ xlr_board_info.gmac_block[0].credit_config = &cc_table_gmac;
+ xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0;
+ xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0;
+ xlr_board_info.gmac_block[0].mode = XLR_RGMII;
+ xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET;
+ xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ;
+ xlr_board_info.gmac_block[0].baseinst = 0;
+
+ /* XGMAC0 */
+ xlr_board_info.gmac_block[1].type = XLR_XGMAC;
+ xlr_board_info.gmac_block[1].enabled = 1;
+ xlr_board_info.gmac_block[1].credit_config = &cc_table_xgs_0;
+ xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_XGS0_TX;
+ xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_XGS0FR;
+ xlr_board_info.gmac_block[1].mode = -1;
+ xlr_board_info.gmac_block[1].baseaddr = XLR_IO_XGMAC_0_OFFSET;
+ xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ;
+ xlr_board_info.gmac_block[1].baseinst = 4;
+
+ /* XGMAC1 */
+ xlr_board_info.gmac_block[2].type = XLR_XGMAC;
+ xlr_board_info.gmac_block[2].enabled = 1;
+ xlr_board_info.gmac_block[2].credit_config = &cc_table_xgs_1;
+ xlr_board_info.gmac_block[2].station_txbase = MSGRNG_STNID_XGS1_TX;
+ xlr_board_info.gmac_block[2].station_rfr = MSGRNG_STNID_XGS1FR;
+ xlr_board_info.gmac_block[2].mode = -1;
+ xlr_board_info.gmac_block[2].baseaddr = XLR_IO_XGMAC_1_OFFSET;
+ xlr_board_info.gmac_block[2].baseirq = PIC_XGS_1_IRQ;
+ xlr_board_info.gmac_block[2].baseinst = 5;
+ }
+ return 0;
+}
diff --git a/sys/mips/rmi/board.h b/sys/mips/rmi/board.h
new file mode 100644
index 0000000..f47654e
--- /dev/null
+++ b/sys/mips/rmi/board.h
@@ -0,0 +1,282 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#ifndef _RMI_BOARD_H_
+#define _RMI_BOARD_H_
+
+#define RMI_XLR_BOARD_ARIZONA_I 1
+#define RMI_XLR_BOARD_ARIZONA_II 2
+#define RMI_XLR_BOARD_ARIZONA_III 3
+#define RMI_XLR_BOARD_ARIZONA_IV 4
+#define RMI_XLR_BOARD_ARIZONA_V 5
+#define RMI_XLR_BOARD_ARIZONA_VI 6
+#define RMI_XLR_BOARD_ARIZONA_VII 7
+#define RMI_XLR_BOARD_ARIZONA_VIII 8
+
+#define RMI_CHIP_XLR308_A0 0x0c0600
+#define RMI_CHIP_XLR508_A0 0x0c0700
+#define RMI_CHIP_XLR516_A0 0x0c0800
+#define RMI_CHIP_XLR532_A0 0x0c0900
+#define RMI_CHIP_XLR716_A0 0x0c0a00
+#define RMI_CHIP_XLR732_A0 0x0c0b00
+
+#define RMI_CHIP_XLR308_A1 0x0c0601
+#define RMI_CHIP_XLR508_A1 0x0c0701
+#define RMI_CHIP_XLR516_A1 0x0c0801
+#define RMI_CHIP_XLR532_A1 0x0c0901
+#define RMI_CHIP_XLR716_A1 0x0c0a01
+#define RMI_CHIP_XLR732_A1 0x0c0b01
+
+#define RMI_CHIP_XLR308_B0 0x0c0602
+#define RMI_CHIP_XLR508_B0 0x0c0702
+#define RMI_CHIP_XLR516_B0 0x0c0802
+#define RMI_CHIP_XLR532_B0 0x0c0902
+#define RMI_CHIP_XLR716_B0 0x0c0a02
+#define RMI_CHIP_XLR732_B0 0x0c0b02
+
+#define RMI_CHIP_XLR308_B1 0x0c0603
+#define RMI_CHIP_XLR508_B1 0x0c0703
+#define RMI_CHIP_XLR516_B1 0x0c0803
+#define RMI_CHIP_XLR532_B1 0x0c0903
+#define RMI_CHIP_XLR716_B1 0x0c0a03
+#define RMI_CHIP_XLR732_B1 0x0c0b03
+
+#define RMI_CHIP_XLR308_B2 0x0c0604
+#define RMI_CHIP_XLR508_B2 0x0c0704
+#define RMI_CHIP_XLR516_B2 0x0c0804
+#define RMI_CHIP_XLR532_B2 0x0c0904
+#define RMI_CHIP_XLR716_B2 0x0c0a04
+#define RMI_CHIP_XLR732_B2 0x0c0b04
+
+#define RMI_CHIP_XLR308_C0 0x0c0705
+#define RMI_CHIP_XLR508_C0 0x0c0b05
+#define RMI_CHIP_XLR516_C0 0x0c0a05
+#define RMI_CHIP_XLR532_C0 0x0c0805
+#define RMI_CHIP_XLR716_C0 0x0c0205
+#define RMI_CHIP_XLR732_C0 0x0c0005
+
+#define RMI_CHIP_XLR308_C1 0x0c0706
+#define RMI_CHIP_XLR508_C1 0x0c0b06
+#define RMI_CHIP_XLR516_C1 0x0c0a06
+#define RMI_CHIP_XLR532_C1 0x0c0806
+#define RMI_CHIP_XLR716_C1 0x0c0206
+#define RMI_CHIP_XLR732_C1 0x0c0006
+
+#define RMI_CHIP_XLR308_C2 0x0c0707
+#define RMI_CHIP_XLR508_C2 0x0c0b07
+#define RMI_CHIP_XLR516_C2 0x0c0a07
+#define RMI_CHIP_XLR532_C2 0x0c0807
+#define RMI_CHIP_XLR716_C2 0x0c0207
+#define RMI_CHIP_XLR732_C2 0x0c0007
+
+#define RMI_CHIP_XLR308_C3 0x0c0708
+#define RMI_CHIP_XLR508_C3 0x0c0b08
+#define RMI_CHIP_XLR516_C3 0x0c0a08
+#define RMI_CHIP_XLR532_C3 0x0c0808
+#define RMI_CHIP_XLR716_C3 0x0c0208
+#define RMI_CHIP_XLR732_C3 0x0c0008
+
+#define RMI_CHIP_XLR308_C4 0x0c0709
+#define RMI_CHIP_XLR508_C4 0x0c0b09
+#define RMI_CHIP_XLR516_C4 0x0c0a09
+#define RMI_CHIP_XLR532_C4 0x0c0809
+#define RMI_CHIP_XLR716_C4 0x0c0209
+#define RMI_CHIP_XLR732_C4 0x0c0009
+
+#define RMI_CHIP_XLS608_A0 0x0c8000
+#define RMI_CHIP_XLS408_A0 0x0c8800
+#define RMI_CHIP_XLS404_A0 0x0c8c00
+#define RMI_CHIP_XLS208_A0 0x0c8e00
+#define RMI_CHIP_XLS204_A0 0x0c8f00
+
+#define RMI_CHIP_XLS608_A1 0x0c8001
+#define RMI_CHIP_XLS408_A1 0x0c8801
+#define RMI_CHIP_XLS404_A1 0x0c8c01
+#define RMI_CHIP_XLS208_A1 0x0c8e01
+#define RMI_CHIP_XLS204_A1 0x0c8f01
+
+static __inline__ unsigned int
+xlr_revision(void)
+{
+ return mips_rd_prid() & 0xff00ff;
+}
+
+static __inline__ unsigned int
+xlr_is_xls(void)
+{
+ uint32_t prid = mips_rd_prid();
+
+ return (prid & 0xf000) == 0x8000 || (prid & 0xf000) == 0x4000;
+}
+
+static __inline__ int
+xlr_revision_a0(void)
+{
+ return xlr_revision() == 0x0c0000;
+}
+
+static __inline__ int
+xlr_revision_b0(void)
+{
+ return xlr_revision() == 0x0c0002;
+}
+
+static __inline__ int
+xlr_revision_b1(void)
+{
+ return xlr_revision() == 0x0c0003;
+}
+
+static __inline__ int
+xlr_board_atx_i(void)
+{
+ return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_I;
+}
+
+static __inline__ int
+xlr_board_atx_ii(void)
+{
+ return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_II;
+}
+
+static __inline__ int
+xlr_board_atx_ii_b(void)
+{
+ return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_II)
+ && (xlr_boot1_info.board_minor_version == 1);
+}
+
+static __inline__ int
+xlr_board_atx_iii(void)
+{
+ return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III;
+}
+
+static __inline__ int
+xlr_board_atx_iv(void)
+{
+ return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_IV)
+ && (xlr_boot1_info.board_minor_version == 0);
+}
+static __inline__ int
+xlr_board_atx_iv_b(void)
+{
+ return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_IV)
+ && (xlr_boot1_info.board_minor_version == 1);
+}
+static __inline__ int
+xlr_board_atx_v(void)
+{
+ return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_V;
+}
+static __inline__ int
+xlr_board_atx_vi(void)
+{
+ return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI;
+}
+
+static __inline__ int
+xlr_board_atx_iii_256(void)
+{
+ return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III)
+ && (xlr_boot1_info.board_minor_version == 0);
+}
+
+static __inline__ int
+xlr_board_atx_iii_512(void)
+{
+ return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III)
+ && (xlr_boot1_info.board_minor_version == 1);
+}
+
+static __inline__ int
+xlr_board_atx_v_512(void)
+{
+ return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_V)
+ && (xlr_boot1_info.board_minor_version == 1);
+}
+
+static __inline__ int
+xlr_board_pci(void)
+{
+ return (xlr_board_atx_iii_256() || xlr_board_atx_iii_512()
+ || xlr_board_atx_v_512());
+}
+static __inline__ int
+xlr_is_xls2xx(void)
+{
+ uint32_t chipid = mips_rd_prid() & 0xffffff00U;
+
+ return chipid == 0x0c8e00 || chipid == 0x0c8f00;
+}
+
+static __inline__ int
+xlr_is_xls4xx(void)
+{
+ uint32_t chipid = mips_rd_prid() & 0xffffff00U;
+
+ return chipid == 0x0c8800 || chipid == 0x0c8c00;
+}
+
+/* all our knowledge of chip and board that cannot be detected run-time goes here */
+enum gmac_block_types {
+ XLR_GMAC, XLR_XGMAC, XLR_SPI4
+};
+enum gmac_block_modes {
+ XLR_RGMII, XLR_SGMII, XLR_PORT0_RGMII
+};
+struct xlr_board_info {
+ int is_xls;
+ int nr_cpus;
+ int usb; /* usb enabled ? */
+ int cfi; /* compact flash driver for NOR? */
+ int pci_irq;
+ struct stn_cc **credit_configs; /* pointer to Core station credits */
+ struct bucket_size *bucket_sizes; /* pointer to Core station
+ * bucket */
+ int *msgmap; /* mapping of message station to devices */
+ int gmacports; /* number of gmac ports on the board */
+ struct xlr_gmac_block_t {
+ int type; /* see enum gmac_block_types */
+ unsigned int enabled; /* mask of ports enabled */
+ struct stn_cc *credit_config; /* credit configuration */
+ int station_txbase; /* station id for tx */
+ int station_rfr;/* free desc bucket */
+ int mode; /* see gmac_block_modes */
+ uint32_t baseaddr; /* IO base */
+ int baseirq; /* first irq for this block, the rest are in
+ * sequence */
+ int baseinst; /* the first rge unit for this block */
+ } gmac_block[3];
+};
+
+extern struct xlr_board_info xlr_board_info;
+int xlr_board_info_setup(void);
+
+#endif
diff --git a/sys/mips/rmi/bus_space_rmi.c b/sys/mips/rmi/bus_space_rmi.c
new file mode 100644
index 0000000..568eaca
--- /dev/null
+++ b/sys/mips/rmi/bus_space_rmi.c
@@ -0,0 +1,831 @@
+/*-
+ * Copyright (c) 2009 RMI Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/ktr.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_extern.h>
+
+#include <machine/bus.h>
+#include <machine/cache.h>
+void xlr_print_int(uint32_t);
+
+static int
+rmi_bus_space_map(void *t, bus_addr_t addr,
+ bus_size_t size, int flags,
+ bus_space_handle_t * bshp);
+
+
+static void
+rmi_bus_space_unmap(void *t, bus_space_handle_t bsh,
+ bus_size_t size);
+
+static int
+rmi_bus_space_subregion(void *t,
+ bus_space_handle_t bsh,
+ bus_size_t offset, bus_size_t size,
+ bus_space_handle_t * nbshp);
+
+static u_int8_t
+rmi_bus_space_read_1(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset);
+
+static u_int16_t
+rmi_bus_space_read_2(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset);
+
+static u_int32_t
+rmi_bus_space_read_4(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset);
+
+static void
+rmi_bus_space_read_multi_1(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset, u_int8_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_read_multi_2(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset, u_int16_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_read_multi_4(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset, u_int32_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_read_region_1(void *t,
+ bus_space_handle_t bsh,
+ bus_size_t offset, u_int8_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_read_region_2(void *t,
+ bus_space_handle_t bsh,
+ bus_size_t offset, u_int16_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_read_region_4(void *t,
+ bus_space_handle_t bsh,
+ bus_size_t offset, u_int32_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_write_1(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset, u_int8_t value);
+
+static void
+rmi_bus_space_write_2(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset, u_int16_t value);
+
+static void
+rmi_bus_space_write_4(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset, u_int32_t value);
+
+static void
+rmi_bus_space_write_multi_1(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset,
+ const u_int8_t * addr,
+ size_t count);
+static void
+rmi_bus_space_write_multi_2(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset,
+ const u_int16_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_write_multi_4(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset,
+ const u_int32_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_write_region_2(void *t,
+ bus_space_handle_t bsh,
+ bus_size_t offset,
+ const u_int16_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_write_region_4(void *t,
+ bus_space_handle_t bsh,
+ bus_size_t offset,
+ const u_int32_t * addr,
+ size_t count);
+
+
+static void
+rmi_bus_space_set_region_2(void *t,
+ bus_space_handle_t bsh,
+ bus_size_t offset, u_int16_t value,
+ size_t count);
+static void
+rmi_bus_space_set_region_4(void *t,
+ bus_space_handle_t bsh,
+ bus_size_t offset, u_int32_t value,
+ size_t count);
+
+static void
+rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused,
+ bus_size_t offset __unused, bus_size_t len __unused, int flags);
+
+
+static void
+rmi_bus_space_copy_region_2(void *t,
+ bus_space_handle_t bsh1,
+ bus_size_t off1,
+ bus_space_handle_t bsh2,
+ bus_size_t off2, size_t count);
+
+u_int8_t
+rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle,
+ bus_size_t offset);
+
+static u_int16_t
+rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle,
+ bus_size_t offset);
+
+static u_int32_t
+rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle,
+ bus_size_t offset);
+static void
+rmi_bus_space_read_multi_stream_1(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset, u_int8_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_read_multi_stream_2(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset, u_int16_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_read_multi_stream_4(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset, u_int32_t * addr,
+ size_t count);
+
+void
+rmi_bus_space_write_stream_1(void *t, bus_space_handle_t bsh,
+ bus_size_t offset, u_int8_t value);
+static void
+rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle,
+ bus_size_t offset, u_int16_t value);
+
+static void
+rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle,
+ bus_size_t offset, u_int32_t value);
+
+static void
+rmi_bus_space_write_multi_stream_1(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset,
+ const u_int8_t * addr,
+ size_t count);
+static void
+rmi_bus_space_write_multi_stream_2(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset,
+ const u_int16_t * addr,
+ size_t count);
+
+static void
+rmi_bus_space_write_multi_stream_4(void *t,
+ bus_space_handle_t handle,
+ bus_size_t offset,
+ const u_int32_t * addr,
+ size_t count);
+
+
+static struct bus_space local_rmi_bus_space = {
+ /* cookie */
+ (void *)0,
+
+ /* mapping/unmapping */
+ rmi_bus_space_map,
+ rmi_bus_space_unmap,
+ rmi_bus_space_subregion,
+
+ /* allocation/deallocation */
+ NULL,
+ NULL,
+
+ /* barrier */
+ rmi_bus_space_barrier,
+
+ /* read (single) */
+ rmi_bus_space_read_1,
+ rmi_bus_space_read_2,
+ rmi_bus_space_read_4,
+ NULL,
+
+ /* read multiple */
+ rmi_bus_space_read_multi_1,
+ rmi_bus_space_read_multi_2,
+ rmi_bus_space_read_multi_4,
+ NULL,
+
+ /* read region */
+ rmi_bus_space_read_region_1,
+ rmi_bus_space_read_region_2,
+ rmi_bus_space_read_region_4,
+ NULL,
+
+ /* write (single) */
+ rmi_bus_space_write_1,
+ rmi_bus_space_write_2,
+ rmi_bus_space_write_4,
+ NULL,
+
+ /* write multiple */
+ rmi_bus_space_write_multi_1,
+ rmi_bus_space_write_multi_2,
+ rmi_bus_space_write_multi_4,
+ NULL,
+
+ /* write region */
+ NULL,
+ rmi_bus_space_write_region_2,
+ rmi_bus_space_write_region_4,
+ NULL,
+
+ /* set multiple */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ /* set region */
+ NULL,
+ rmi_bus_space_set_region_2,
+ rmi_bus_space_set_region_4,
+ NULL,
+
+ /* copy */
+ NULL,
+ rmi_bus_space_copy_region_2,
+ NULL,
+ NULL,
+
+ /* read (single) stream */
+ rmi_bus_space_read_stream_1,
+ rmi_bus_space_read_stream_2,
+ rmi_bus_space_read_stream_4,
+ NULL,
+
+ /* read multiple stream */
+ rmi_bus_space_read_multi_stream_1,
+ rmi_bus_space_read_multi_stream_2,
+ rmi_bus_space_read_multi_stream_4,
+ NULL,
+
+ /* read region stream */
+ rmi_bus_space_read_region_1,
+ rmi_bus_space_read_region_2,
+ rmi_bus_space_read_region_4,
+ NULL,
+
+ /* write (single) stream */
+ rmi_bus_space_write_stream_1,
+ rmi_bus_space_write_stream_2,
+ rmi_bus_space_write_stream_4,
+ NULL,
+
+ /* write multiple stream */
+ rmi_bus_space_write_multi_stream_1,
+ rmi_bus_space_write_multi_stream_2,
+ rmi_bus_space_write_multi_stream_4,
+ NULL,
+
+ /* write region stream */
+ NULL,
+ rmi_bus_space_write_region_2,
+ rmi_bus_space_write_region_4,
+ NULL,
+};
+
+/* generic bus_space tag */
+bus_space_tag_t rmi_bus_space = &local_rmi_bus_space;
+
+#define MIPS_BUS_SPACE_IO 0 /* space is i/o space */
+#define MIPS_BUS_SPACE_MEM 1 /* space is mem space */
+#define MIPS_BUS_SPACE_PCI 10 /* avoid conflict with other spaces */
+
+#define BUS_SPACE_UNRESTRICTED (~0)
+
+#define SWAP32(x)\
+ (((x) & 0xff000000) >> 24) | \
+ (((x) & 0x000000ff) << 24) | \
+ (((x) & 0x0000ff00) << 8) | \
+ (((x) & 0x00ff0000) >> 8)
+
+#define SWAP16(x)\
+ (((x) & 0xff00) >> 8) | \
+ (((x) & 0x00ff) << 8)
+
+/*
+ * Map a region of device bus space into CPU virtual address space.
+ */
+
+
+static int
+rmi_bus_space_map(void *t __unused, bus_addr_t addr,
+ bus_size_t size __unused, int flags __unused,
+ bus_space_handle_t * bshp)
+{
+
+ *bshp = addr;
+ return (0);
+}
+
+/*
+ * Unmap a region of device bus space.
+ */
+static void
+rmi_bus_space_unmap(void *t __unused, bus_space_handle_t bsh __unused,
+ bus_size_t size __unused)
+{
+}
+
+/*
+ * Get a new handle for a subregion of an already-mapped area of bus space.
+ */
+
+static int
+rmi_bus_space_subregion(void *t __unused, bus_space_handle_t bsh,
+ bus_size_t offset, bus_size_t size __unused,
+ bus_space_handle_t * nbshp)
+{
+ *nbshp = bsh + offset;
+ return (0);
+}
+
+/*
+ * Read a 1, 2, 4, or 8 byte quantity from bus space
+ * described by tag/handle/offset.
+ */
+
+static u_int8_t
+rmi_bus_space_read_1(void *tag, bus_space_handle_t handle,
+ bus_size_t offset)
+{
+ if ((int)tag == MIPS_BUS_SPACE_PCI)
+ return (u_int8_t) (*(volatile u_int8_t *)(handle + offset));
+ else
+ return (u_int8_t) (*(volatile u_int32_t *)(handle + offset));
+}
+
+static u_int16_t
+rmi_bus_space_read_2(void *tag, bus_space_handle_t handle,
+ bus_size_t offset)
+{
+ if ((int)tag == MIPS_BUS_SPACE_PCI)
+ return SWAP16((u_int16_t) (*(volatile u_int16_t *)(handle + offset)));
+ else
+ return *(volatile u_int16_t *)(handle + offset);
+}
+
+static u_int32_t
+rmi_bus_space_read_4(void *tag, bus_space_handle_t handle,
+ bus_size_t offset)
+{
+ if ((int)tag == MIPS_BUS_SPACE_PCI)
+ return SWAP32((*(volatile u_int32_t *)(handle + offset)));
+ else
+ return (*(volatile u_int32_t *)(handle + offset));
+}
+
+
+
+/*
+ * Read `count' 1, 2, 4, or 8 byte quantities from bus space
+ * described by tag/handle/offset and copy into buffer provided.
+ */
+static void
+rmi_bus_space_read_multi_1(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, u_int8_t * addr, size_t count)
+{
+
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ *addr = (*(volatile u_int8_t *)(handle + offset));
+ addr++;
+ }
+}
+
+static void
+rmi_bus_space_read_multi_2(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, u_int16_t * addr, size_t count)
+{
+
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ *addr = *(volatile u_int16_t *)(handle + offset);
+ *addr = SWAP16(*addr);
+ addr++;
+ }
+}
+
+static void
+rmi_bus_space_read_multi_4(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, u_int32_t * addr, size_t count)
+{
+
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ *addr = *(volatile u_int32_t *)(handle + offset);
+ *addr = SWAP32(*addr);
+ addr++;
+ }
+}
+
+/*
+ * Write the 1, 2, 4, or 8 byte value `value' to bus space
+ * described by tag/handle/offset.
+ */
+
+
+static void
+rmi_bus_space_write_1(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, u_int8_t value)
+{
+ mips_sync();
+ if ((int)tag == MIPS_BUS_SPACE_PCI)
+ *(volatile u_int8_t *)(handle + offset) = value;
+ else
+ *(volatile u_int32_t *)(handle + offset) = (u_int32_t) value;
+}
+
+static void
+rmi_bus_space_write_2(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, u_int16_t value)
+{
+ mips_sync();
+ if ((int)tag == MIPS_BUS_SPACE_PCI) {
+ *(volatile u_int16_t *)(handle + offset) = SWAP16(value);
+ } else
+ *(volatile u_int16_t *)(handle + offset) = value;
+}
+
+
+static void
+rmi_bus_space_write_4(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, u_int32_t value)
+{
+ mips_sync();
+ if ((int)tag == MIPS_BUS_SPACE_PCI) {
+ *(volatile u_int32_t *)(handle + offset) = SWAP32(value);
+ } else
+ *(volatile u_int32_t *)(handle + offset) = value;
+}
+
+
+
+/*
+ * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
+ * provided to bus space described by tag/handle/offset.
+ */
+
+
+static void
+rmi_bus_space_write_multi_1(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, const u_int8_t * addr, size_t count)
+{
+ mips_sync();
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ (*(volatile u_int8_t *)(handle + offset)) = *addr;
+ addr++;
+ }
+}
+
+static void
+rmi_bus_space_write_multi_2(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, const u_int16_t * addr, size_t count)
+{
+ mips_sync();
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ (*(volatile u_int16_t *)(handle + offset)) = SWAP16(*addr);
+ addr++;
+ }
+}
+
+static void
+rmi_bus_space_write_multi_4(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, const u_int32_t * addr, size_t count)
+{
+ mips_sync();
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ (*(volatile u_int32_t *)(handle + offset)) = SWAP32(*addr);
+ addr++;
+ }
+}
+
+/*
+ * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
+ * by tag/handle starting at `offset'.
+ */
+
+static void
+rmi_bus_space_set_region_2(void *t, bus_space_handle_t bsh,
+ bus_size_t offset, u_int16_t value, size_t count)
+{
+ bus_addr_t addr = bsh + offset;
+
+ for (; count != 0; count--, addr += 2)
+ (*(volatile u_int16_t *)(addr)) = value;
+}
+
+static void
+rmi_bus_space_set_region_4(void *t, bus_space_handle_t bsh,
+ bus_size_t offset, u_int32_t value, size_t count)
+{
+ bus_addr_t addr = bsh + offset;
+
+ for (; count != 0; count--, addr += 4)
+ (*(volatile u_int32_t *)(addr)) = value;
+}
+
+
+/*
+ * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
+ * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
+ */
+static void
+rmi_bus_space_copy_region_2(void *t, bus_space_handle_t bsh1,
+ bus_size_t off1, bus_space_handle_t bsh2,
+ bus_size_t off2, size_t count)
+{
+ printf("bus_space_copy_region_2 - unimplemented\n");
+}
+
+/*
+ * Read `count' 1, 2, 4, or 8 byte quantities from bus space
+ * described by tag/handle/offset and copy into buffer provided.
+ */
+
+u_int8_t
+rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle,
+ bus_size_t offset)
+{
+
+ return *((volatile u_int8_t *)(handle + offset));
+}
+
+
+static u_int16_t
+rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle,
+ bus_size_t offset)
+{
+ return *(volatile u_int16_t *)(handle + offset);
+}
+
+
+static u_int32_t
+rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle,
+ bus_size_t offset)
+{
+ return (*(volatile u_int32_t *)(handle + offset));
+}
+
+
+static void
+rmi_bus_space_read_multi_stream_1(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, u_int8_t * addr, size_t count)
+{
+
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ *addr = (*(volatile u_int8_t *)(handle + offset));
+ addr++;
+ }
+}
+
+static void
+rmi_bus_space_read_multi_stream_2(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, u_int16_t * addr, size_t count)
+{
+
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ *addr = (*(volatile u_int16_t *)(handle + offset));
+ addr++;
+ }
+}
+
+static void
+rmi_bus_space_read_multi_stream_4(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, u_int32_t * addr, size_t count)
+{
+
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ *addr = (*(volatile u_int32_t *)(handle + offset));
+ addr++;
+ }
+}
+
+
+
+/*
+ * Read `count' 1, 2, 4, or 8 byte quantities from bus space
+ * described by tag/handle and starting at `offset' and copy into
+ * buffer provided.
+ */
+void
+rmi_bus_space_read_region_1(void *t, bus_space_handle_t bsh,
+ bus_size_t offset, u_int8_t * addr, size_t count)
+{
+ bus_addr_t baddr = bsh + offset;
+
+ while (count--) {
+ *addr++ = (*(volatile u_int8_t *)(baddr));
+ baddr += 1;
+ }
+}
+
+void
+rmi_bus_space_read_region_2(void *t, bus_space_handle_t bsh,
+ bus_size_t offset, u_int16_t * addr, size_t count)
+{
+ bus_addr_t baddr = bsh + offset;
+
+ while (count--) {
+ *addr++ = (*(volatile u_int16_t *)(baddr));
+ baddr += 2;
+ }
+}
+
+void
+rmi_bus_space_read_region_4(void *t, bus_space_handle_t bsh,
+ bus_size_t offset, u_int32_t * addr, size_t count)
+{
+ bus_addr_t baddr = bsh + offset;
+
+ while (count--) {
+ *addr++ = (*(volatile u_int32_t *)(baddr));
+ baddr += 4;
+ }
+}
+
+
+void
+rmi_bus_space_write_stream_1(void *t, bus_space_handle_t handle,
+ bus_size_t offset, u_int8_t value)
+{
+ mips_sync();
+ *(volatile u_int8_t *)(handle + offset) = value;
+}
+
+
+static void
+rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle,
+ bus_size_t offset, u_int16_t value)
+{
+ mips_sync();
+ *(volatile u_int16_t *)(handle + offset) = value;
+}
+
+
+static void
+rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle,
+ bus_size_t offset, u_int32_t value)
+{
+ mips_sync();
+ *(volatile u_int32_t *)(handle + offset) = value;
+}
+
+
+static void
+rmi_bus_space_write_multi_stream_1(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, const u_int8_t * addr, size_t count)
+{
+ mips_sync();
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ (*(volatile u_int8_t *)(handle + offset)) = *addr;
+ addr++;
+ }
+}
+
+static void
+rmi_bus_space_write_multi_stream_2(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, const u_int16_t * addr, size_t count)
+{
+ mips_sync();
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ (*(volatile u_int16_t *)(handle + offset)) = *addr;
+ addr++;
+ }
+}
+
+static void
+rmi_bus_space_write_multi_stream_4(void *tag, bus_space_handle_t handle,
+ bus_size_t offset, const u_int32_t * addr, size_t count)
+{
+ mips_sync();
+ if ((int)tag != MIPS_BUS_SPACE_PCI)
+ return;
+ while (count--) {
+ (*(volatile u_int32_t *)(handle + offset)) = *addr;
+ addr++;
+ }
+}
+
+void
+rmi_bus_space_write_region_2(void *t,
+ bus_space_handle_t bsh,
+ bus_size_t offset,
+ const u_int16_t * addr,
+ size_t count)
+{
+ bus_addr_t baddr = (bus_addr_t) bsh + offset;
+
+ while (count--) {
+ (*(volatile u_int16_t *)(baddr)) = *addr;
+ addr++;
+ baddr += 2;
+ }
+}
+
+void
+rmi_bus_space_write_region_4(void *t, bus_space_handle_t bsh,
+ bus_size_t offset, const u_int32_t * addr, size_t count)
+{
+ bus_addr_t baddr = bsh + offset;
+
+ while (count--) {
+ (*(volatile u_int32_t *)(baddr)) = *addr;
+ addr++;
+ baddr += 4;
+ }
+}
+
+static void
+rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused,
+ bus_size_t offset __unused, bus_size_t len __unused, int flags)
+{
+
+}
diff --git a/sys/mips/rmi/clock.c b/sys/mips/rmi/clock.c
new file mode 100644
index 0000000..d976297
--- /dev/null
+++ b/sys/mips/rmi/clock.c
@@ -0,0 +1,346 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/smp.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#include <sys/timetc.h>
+
+#include <sys/module.h>
+#include <sys/stdint.h>
+
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/systm.h>
+#include <sys/clock.h>
+
+#include <machine/clock.h>
+#include <machine/md_var.h>
+#include <machine/hwfunc.h>
+#include <machine/intr_machdep.h>
+
+#include <mips/rmi/iomap.h>
+#include <mips/rmi/clock.h>
+#include <mips/rmi/interrupt.h>
+#include <mips/rmi/pic.h>
+#include <mips/rmi/shared_structs.h>
+
+#ifdef XLR_PERFMON
+#include <mips/rmi/perfmon.h>
+#endif
+
+uint64_t counter_freq;
+uint64_t cycles_per_tick;
+uint64_t cycles_per_usec;
+uint64_t cycles_per_sec;
+uint64_t cycles_per_hz;
+
+u_int32_t counter_upper = 0;
+u_int32_t counter_lower_last = 0;
+
+#define STAT_PROF_CLOCK_SCALE_FACTOR 8
+
+static int scale_factor;
+static int count_scale_factor[32];
+
+uint64_t
+platform_get_frequency()
+{
+ return XLR_PIC_HZ;
+}
+
+void
+mips_timer_early_init(uint64_t clock_hz)
+{
+ /* Initialize clock early so that we can use DELAY sooner */
+ counter_freq = clock_hz;
+ cycles_per_usec = (clock_hz / (1000 * 1000));
+
+}
+
+/*
+* count_compare_clockhandler:
+*
+* Handle the clock interrupt when count becomes equal to
+* compare.
+*/
+int
+count_compare_clockhandler(struct trapframe *tf)
+{
+ int cpu = PCPU_GET(cpuid);
+ uint32_t cycles;
+
+ critical_enter();
+
+ if (cpu == 0) {
+ mips_wr_compare(0);
+ } else {
+ count_scale_factor[cpu]++;
+ cycles = mips_rd_count();
+ cycles += XLR_CPU_HZ / hz;
+ mips_wr_compare(cycles);
+
+ hardclock_cpu(USERMODE(tf->sr));
+ if (count_scale_factor[cpu] == STAT_PROF_CLOCK_SCALE_FACTOR) {
+ statclock(USERMODE(tf->sr));
+ if (profprocs != 0) {
+ profclock(USERMODE(tf->sr), tf->pc);
+ }
+ count_scale_factor[cpu] = 0;
+ }
+ /* If needed , handle count compare tick skew here */
+ }
+
+ critical_exit();
+ return (FILTER_HANDLED);
+}
+
+int
+pic_hardclockhandler(struct trapframe *tf)
+{
+ int cpu = PCPU_GET(cpuid);
+
+ critical_enter();
+
+ if (cpu == 0) {
+ scale_factor++;
+ hardclock(USERMODE(tf->sr), tf->pc);
+ if (scale_factor == STAT_PROF_CLOCK_SCALE_FACTOR) {
+ statclock(USERMODE(tf->sr));
+ if (profprocs != 0) {
+ profclock(USERMODE(tf->sr), tf->pc);
+ }
+ scale_factor = 0;
+ }
+#ifdef XLR_PERFMON
+ if (xlr_perfmon_started)
+ xlr_perfmon_clockhandler();
+#endif
+
+ } else {
+ /* If needed , handle count compare tick skew here */
+ }
+ critical_exit();
+ return (FILTER_HANDLED);
+}
+
+int
+pic_timecounthandler(struct trapframe *tf)
+{
+ return (FILTER_HANDLED);
+}
+
+void
+rmi_early_counter_init()
+{
+ int cpu = PCPU_GET(cpuid);
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+
+ /*
+ * We do this to get the PIC time counter running right after system
+ * start. Otherwise the DELAY() function will not be able to work
+ * since it won't have a TC to read.
+ */
+ xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff));
+ xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0xffffffff & 0xffffffff));
+ xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu));
+ xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_6_IRQ));
+ pic_update_control(1 << (8 + 6));
+}
+
+void tick_init(void);
+
+void
+platform_initclocks(void)
+{
+ int cpu = PCPU_GET(cpuid);
+ void *cookie;
+
+ /*
+ * Note: Passing #3 as NULL ensures that clockhandler gets called
+ * with trapframe
+ */
+ /* profiling/process accounting timer interrupt for non-zero cpus */
+ cpu_establish_hardintr("compare",
+ (driver_filter_t *) count_compare_clockhandler,
+ NULL,
+ NULL,
+ IRQ_TIMER,
+ INTR_TYPE_CLK | INTR_FAST, &cookie);
+
+ /* timekeeping timer interrupt for cpu 0 */
+ cpu_establish_hardintr("hardclk",
+ (driver_filter_t *) pic_hardclockhandler,
+ NULL,
+ NULL,
+ PIC_TIMER_7_IRQ,
+ INTR_TYPE_CLK | INTR_FAST,
+ &cookie);
+
+ /* this is used by timecounter */
+ cpu_establish_hardintr("timecount",
+ (driver_filter_t *) pic_timecounthandler, NULL,
+ NULL, PIC_TIMER_6_IRQ, INTR_TYPE_CLK | INTR_FAST,
+ &cookie);
+
+ if (cpu == 0) {
+ __uint64_t maxval = XLR_PIC_HZ / hz;
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+
+ stathz = hz / STAT_PROF_CLOCK_SCALE_FACTOR;
+ profhz = stathz;
+
+ /* Setup PIC Interrupt */
+
+ if (rmi_spin_mutex_safe)
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff)); /* 0x100 + 7 */
+ xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff); /* 0x110 + 7 */
+ /* 0x40 + 8 */
+ /* reg 40 is lower bits 31-0 and holds CPU mask */
+ xlr_write_reg(mmio, PIC_IRT_0_TIMER_7, (1 << cpu));
+ /* 0x80 + 8 */
+ /* Reg 80 is upper bits 63-32 and holds */
+ /* Valid Edge Local IRQ */
+ xlr_write_reg(mmio, PIC_IRT_1_TIMER_7, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_7_IRQ));
+ pic_update_control(1 << (8 + 7));
+
+ xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff));
+ xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0x0 & 0xffffffff));
+ xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu));
+ xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_6_IRQ));
+ pic_update_control(1 << (8 + 6));
+ if (rmi_spin_mutex_safe)
+ mtx_unlock_spin(&xlr_pic_lock);
+ } else {
+ /* Setup count-compare interrupt for vcpu[1-31] */
+ mips_wr_compare((xlr_boot1_info.cpu_frequency) / hz);
+ }
+ tick_init();
+}
+
+unsigned
+__attribute__((no_instrument_function))
+platform_get_timecount(struct timecounter *tc __unused)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+
+ return 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0);
+}
+
+void
+DELAY(int n)
+{
+ uint32_t cur, last, delta, usecs;
+
+ /*
+ * This works by polling the timer and counting the number of
+ * microseconds that go by.
+ */
+ last = platform_get_timecount(NULL);
+ delta = usecs = 0;
+
+ while (n > usecs) {
+ cur = platform_get_timecount(NULL);
+
+ /* Check to see if the timer has wrapped around. */
+ if (cur < last)
+ delta += (cur + (cycles_per_hz - last));
+ else
+ delta += (cur - last);
+
+ last = cur;
+
+ if (delta >= cycles_per_usec) {
+ usecs += delta / cycles_per_usec;
+ delta %= cycles_per_usec;
+ }
+ }
+}
+
+static
+uint64_t
+read_pic_counter(void)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+ uint32_t lower, upper;
+ uint64_t tc;
+
+ /*
+ * Pull the value of the 64 bit counter which is stored in PIC
+ * register 120+N and 130+N
+ */
+ upper = 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_1);
+ lower = 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0);
+ tc = (((uint64_t) upper << 32) | (uint64_t) lower);
+ return (tc);
+}
+
+extern struct timecounter counter_timecounter;
+
+void
+mips_timer_init_params(uint64_t platform_counter_freq, int double_count)
+{
+
+ /*
+ * XXX: Do not use printf here: uart code 8250 may use DELAY so this
+ * function should be called before cninit.
+ */
+ counter_freq = platform_counter_freq;
+ /*
+ * XXX: Some MIPS32 cores update the Count register only every two
+ * pipeline cycles.
+ */
+ if (double_count != 0)
+ counter_freq /= 2;
+
+ cycles_per_tick = counter_freq / 1000;
+ cycles_per_hz = counter_freq / hz;
+ cycles_per_usec = counter_freq / (1 * 1000 * 1000);
+ cycles_per_sec = counter_freq;
+
+ counter_timecounter.tc_frequency = counter_freq;
+ printf("hz=%d cyl_per_hz:%jd cyl_per_usec:%jd freq:%jd cyl_per_hz:%jd cyl_per_sec:%jd\n",
+ hz,
+ cycles_per_tick,
+ cycles_per_usec,
+ counter_freq,
+ cycles_per_hz,
+ cycles_per_sec
+ );
+ set_cputicker(read_pic_counter, counter_freq, 1);
+}
diff --git a/sys/mips/rmi/clock.h b/sys/mips/rmi/clock.h
new file mode 100644
index 0000000..c067581
--- /dev/null
+++ b/sys/mips/rmi/clock.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#ifndef _RMI_CLOCK_H_
+#define _RMI_CLOCK_H_
+
+#define XLR_PIC_HZ 66000000U
+#define XLR_CPU_HZ (xlr_boot1_info.cpu_frequency)
+
+int count_compare_clockhandler(struct trapframe *);
+int pic_hardclockhandler(struct trapframe *);
+int pic_timecounthandler(struct trapframe *);
+void rmi_early_counter_init(void);
+
+#endif /* _RMI_CLOCK_H_ */
diff --git a/sys/mips/rmi/debug.h b/sys/mips/rmi/debug.h
new file mode 100755
index 0000000..b5ec144
--- /dev/null
+++ b/sys/mips/rmi/debug.h
@@ -0,0 +1,103 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#ifndef _RMI_DEBUG_H_
+#define _RMI_DEBUG_H_
+
+#include <machine/atomic.h>
+
+enum {
+ //cacheline 0
+ MSGRNG_INT,
+ MSGRNG_PIC_INT,
+ MSGRNG_MSG,
+ MSGRNG_EXIT_STATUS,
+ MSGRNG_MSG_CYCLES,
+ //cacheline 1
+ NETIF_TX = 8,
+ NETIF_RX,
+ NETIF_TX_COMPLETE,
+ NETIF_TX_COMPLETE_TX,
+ NETIF_RX_CYCLES,
+ NETIF_TX_COMPLETE_CYCLES,
+ NETIF_TX_CYCLES,
+ NETIF_TIMER_START_Q,
+ //NETIF_REG_FRIN,
+ //NETIF_INT_REG,
+ //cacheline 2
+ REPLENISH_ENTER = 16,
+ REPLENISH_ENTER_COUNT,
+ REPLENISH_CPU,
+ REPLENISH_FRIN,
+ REPLENISH_CYCLES,
+ NETIF_STACK_TX,
+ NETIF_START_Q,
+ NETIF_STOP_Q,
+ //cacheline 3
+ USER_MAC_START = 24,
+ USER_MAC_INT = 24,
+ USER_MAC_TX_COMPLETE,
+ USER_MAC_RX,
+ USER_MAC_POLL,
+ USER_MAC_TX,
+ USER_MAC_TX_FAIL,
+ USER_MAC_TX_COUNT,
+ USER_MAC_FRIN,
+ //cacheline 4
+ USER_MAC_TX_FAIL_GMAC_CREDITS = 32,
+ USER_MAC_DO_PAGE_FAULT,
+ USER_MAC_UPDATE_TLB,
+ USER_MAC_UPDATE_BIGTLB,
+ USER_MAC_UPDATE_TLB_PFN0,
+ USER_MAC_UPDATE_TLB_PFN1,
+
+ XLR_MAX_COUNTERS = 40
+};
+extern int xlr_counters[MAXCPU][XLR_MAX_COUNTERS];
+extern __uint32_t msgrng_msg_cycles;
+
+#ifdef ENABLE_DEBUG
+#define xlr_inc_counter(x) atomic_add_int(&xlr_counters[PCPU_GET(cpuid)][(x)], 1)
+#define xlr_dec_counter(x) atomic_subtract_int(&xlr_counters[PCPU_GET(cpuid)][(x)], 1)
+#define xlr_set_counter(x, value) atomic_set_int(&xlr_counters[PCPU_GET(cpuid)][(x)], (value))
+#define xlr_get_counter(x) (&xlr_counters[0][(x)])
+
+#else /* default mode */
+
+#define xlr_inc_counter(x)
+#define xlr_dec_counter(x)
+#define xlr_set_counter(x, value)
+#define xlr_get_counter(x)
+
+#endif
+
+#define dbg_msg(fmt, args...) printf(fmt, ##args)
+#define dbg_panic(fmt, args...) panic(fmt, ##args)
+
+#endif
diff --git a/sys/mips/rmi/ehcireg.h b/sys/mips/rmi/ehcireg.h
new file mode 100644
index 0000000..9c2540c
--- /dev/null
+++ b/sys/mips/rmi/ehcireg.h
@@ -0,0 +1,309 @@
+/* $NetBSD: ehcireg.h,v 1.18 2004/10/22 10:38:17 augustss Exp $ */
+/* $FreeBSD: src/sys/dev/usb/ehcireg.h,v 1.7.2.2.2.1 2008/10/02 02:57:24 kensmith Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lennart@augustsson.net).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+/*
+ * The EHCI 0.96 spec can be found at
+ * http://developer.intel.com/technology/usb/download/ehci-r096.pdf
+ * and the USB 2.0 spec at
+ * http://www.usb.org/developers/data/usb_20.zip
+ */
+
+#ifndef _DEV_PCI_EHCIREG_H_
+#define _DEV_PCI_EHCIREG_H_
+
+/*** PCI config registers ***/
+
+#define PCI_CBMEM 0x10 /* configuration base MEM */
+
+#define PCI_INTERFACE_EHCI 0x20
+
+#define PCI_USBREV 0x60 /* RO USB protocol revision */
+#define PCI_USBREV_MASK 0xff
+#define PCI_USBREV_PRE_1_0 0x00
+#define PCI_USBREV_1_0 0x10
+#define PCI_USBREV_1_1 0x11
+#define PCI_USBREV_2_0 0x20
+
+#define PCI_EHCI_FLADJ 0x61 /* RW Frame len adj, SOF=59488+6*fladj */
+
+#define PCI_EHCI_PORTWAKECAP 0x62 /* RW Port wake caps (opt) */
+
+/* EHCI Extended Capabilities */
+#define EHCI_EC_LEGSUP 0x01
+
+#define EHCI_EECP_NEXT(x) (((x) >> 8) & 0xff)
+#define EHCI_EECP_ID(x) ((x) & 0xff)
+
+/* Legacy support extended capability */
+#define EHCI_LEGSUP_OS_SEM 0x03 /* OS owned semaphore */
+#define EHCI_LEGSUP_BIOS_SEM 0x02 /* BIOS owned semaphore */
+#define EHCI_LEGSUP_USBLEGCTLSTS 0x04
+
+/*** EHCI capability registers ***/
+
+#define EHCI_CAPLENGTH 0x00 /* RO Capability register length field */
+/* reserved 0x01 */
+#define EHCI_HCIVERSION 0x02 /* RO Interface version number */
+
+#define EHCI_HCSPARAMS 0x04 /* RO Structural parameters */
+#define EHCI_HCS_DEBUGPORT(x) (((x) >> 20) & 0xf)
+#define EHCI_HCS_P_INDICATOR(x) ((x) & 0x10000)
+#define EHCI_HCS_N_CC(x) (((x) >> 12) & 0xf) /* # of companion ctlrs */
+#define EHCI_HCS_N_PCC(x) (((x) >> 8) & 0xf) /* # of ports per comp. */
+#define EHCI_HCS_PPC(x) ((x) & 0x10) /* port power control */
+#define EHCI_HCS_N_PORTS(x) ((x) & 0xf) /* # of ports */
+
+#define EHCI_HCCPARAMS 0x08 /* RO Capability parameters */
+#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */
+#define EHCI_HCC_IST(x) (((x) >> 4) & 0xf) /* isoc sched threshold */
+#define EHCI_HCC_ASPC(x) ((x) & 0x4) /* async sched park cap */
+#define EHCI_HCC_PFLF(x) ((x) & 0x2) /* prog frame list flag */
+#define EHCI_HCC_64BIT(x) ((x) & 0x1) /* 64 bit address cap */
+
+#define EHCI_HCSP_PORTROUTE 0x0c /* RO Companion port route description */
+
+/* EHCI operational registers. Offset given by EHCI_CAPLENGTH register */
+#define EHCI_USBCMD 0x00 /* RO, RW, WO Command register */
+#define EHCI_CMD_ITC_M 0x00ff0000 /* RW interrupt threshold ctrl */
+#define EHCI_CMD_ITC_1 0x00010000
+#define EHCI_CMD_ITC_2 0x00020000
+#define EHCI_CMD_ITC_4 0x00040000
+#define EHCI_CMD_ITC_8 0x00080000
+#define EHCI_CMD_ITC_16 0x00100000
+#define EHCI_CMD_ITC_32 0x00200000
+#define EHCI_CMD_ITC_64 0x00400000
+#define EHCI_CMD_ASPME 0x00000800 /* RW/RO async park enable */
+#define EHCI_CMD_ASPMC 0x00000300 /* RW/RO async park count */
+#define EHCI_CMD_LHCR 0x00000080 /* RW light host ctrl reset */
+#define EHCI_CMD_IAAD 0x00000040 /* RW intr on async adv door
+ * bell */
+#define EHCI_CMD_ASE 0x00000020 /* RW async sched enable */
+#define EHCI_CMD_PSE 0x00000010 /* RW periodic sched enable */
+#define EHCI_CMD_FLS_M 0x0000000c /* RW/RO frame list size */
+#define EHCI_CMD_FLS(x) (((x) >> 2) & 3) /* RW/RO frame list size */
+#define EHCI_CMD_HCRESET 0x00000002 /* RW reset */
+#define EHCI_CMD_RS 0x00000001 /* RW run/stop */
+
+#define EHCI_USBSTS 0x04 /* RO, RW, RWC Status register */
+#define EHCI_STS_ASS 0x00008000 /* RO async sched status */
+#define EHCI_STS_PSS 0x00004000 /* RO periodic sched status */
+#define EHCI_STS_REC 0x00002000 /* RO reclamation */
+#define EHCI_STS_HCH 0x00001000 /* RO host controller halted */
+#define EHCI_STS_IAA 0x00000020 /* RWC interrupt on async adv */
+#define EHCI_STS_HSE 0x00000010 /* RWC host system error */
+#define EHCI_STS_FLR 0x00000008 /* RWC frame list rollover */
+#define EHCI_STS_PCD 0x00000004 /* RWC port change detect */
+#define EHCI_STS_ERRINT 0x00000002 /* RWC error interrupt */
+#define EHCI_STS_INT 0x00000001 /* RWC interrupt */
+#define EHCI_STS_INTRS(x) ((x) & 0x3f)
+
+#define EHCI_NORMAL_INTRS (EHCI_STS_IAA | EHCI_STS_HSE | EHCI_STS_PCD | EHCI_STS_ERRINT | EHCI_STS_INT)
+
+#define EHCI_USBINTR 0x08 /* RW Interrupt register */
+#define EHCI_INTR_IAAE 0x00000020 /* interrupt on async advance
+ * ena */
+#define EHCI_INTR_HSEE 0x00000010 /* host system error ena */
+#define EHCI_INTR_FLRE 0x00000008 /* frame list rollover ena */
+#define EHCI_INTR_PCIE 0x00000004 /* port change ena */
+#define EHCI_INTR_UEIE 0x00000002 /* USB error intr ena */
+#define EHCI_INTR_UIE 0x00000001 /* USB intr ena */
+
+#define EHCI_FRINDEX 0x0c /* RW Frame Index register */
+
+#define EHCI_CTRLDSSEGMENT 0x10 /* RW Control Data Structure Segment */
+
+#define EHCI_PERIODICLISTBASE 0x14 /* RW Periodic List Base */
+#define EHCI_ASYNCLISTADDR 0x18 /* RW Async List Base */
+
+#define EHCI_CONFIGFLAG 0x40 /* RW Configure Flag register */
+#define EHCI_CONF_CF 0x00000001 /* RW configure flag */
+
+#define EHCI_PORTSC(n) (0x40+4*(n)) /* RO, RW, RWC Port Status reg */
+#define EHCI_PS_WKOC_E 0x00400000 /* RW wake on over current ena */
+#define EHCI_PS_WKDSCNNT_E 0x00200000 /* RW wake on disconnect ena */
+#define EHCI_PS_WKCNNT_E 0x00100000 /* RW wake on connect ena */
+#define EHCI_PS_PTC 0x000f0000 /* RW port test control */
+#define EHCI_PS_PIC 0x0000c000 /* RW port indicator control */
+#define EHCI_PS_PO 0x00002000 /* RW port owner */
+#define EHCI_PS_PP 0x00001000 /* RW,RO port power */
+#define EHCI_PS_LS 0x00000c00 /* RO line status */
+#define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == 0x00000400)
+#define EHCI_PS_PR 0x00000100 /* RW port reset */
+#define EHCI_PS_SUSP 0x00000080 /* RW suspend */
+#define EHCI_PS_FPR 0x00000040 /* RW force port resume */
+#define EHCI_PS_OCC 0x00000020 /* RWC over current change */
+#define EHCI_PS_OCA 0x00000010 /* RO over current active */
+#define EHCI_PS_PEC 0x00000008 /* RWC port enable change */
+#define EHCI_PS_PE 0x00000004 /* RW port enable */
+#define EHCI_PS_CSC 0x00000002 /* RWC connect status change */
+#define EHCI_PS_CS 0x00000001 /* RO connect status */
+#define EHCI_PS_CLEAR (EHCI_PS_OCC|EHCI_PS_PEC|EHCI_PS_CSC)
+
+#define EHCI_PORT_RESET_COMPLETE 2 /* ms */
+
+#define EHCI_FLALIGN_ALIGN 0x1000
+
+/* No data structure may cross a page boundary. */
+#define EHCI_PAGE_SIZE 0x1000
+#define EHCI_PAGE(x) ((x) &~ 0xfff)
+#define EHCI_PAGE_OFFSET(x) ((x) & 0xfff)
+#if defined(__FreeBSD__)
+#define EHCI_PAGE_MASK(x) ((x) & 0xfff)
+#endif
+
+typedef u_int32_t ehci_link_t;
+
+#define EHCI_LINK_TERMINATE 0x00000001
+#define EHCI_LINK_TYPE(x) ((x) & 0x00000006)
+#define EHCI_LINK_ITD 0x0
+#define EHCI_LINK_QH 0x2
+#define EHCI_LINK_SITD 0x4
+#define EHCI_LINK_FSTN 0x6
+#define EHCI_LINK_ADDR(x) ((x) &~ 0x1f)
+
+typedef u_int32_t ehci_physaddr_t;
+
+/* Isochronous Transfer Descriptor */
+typedef struct {
+ ehci_link_t itd_next;
+ /* XXX many more */
+} ehci_itd_t;
+
+#define EHCI_ITD_ALIGN 32
+
+/* Split Transaction Isochronous Transfer Descriptor */
+typedef struct {
+ ehci_link_t sitd_next;
+ /* XXX many more */
+} ehci_sitd_t;
+
+#define EHCI_SITD_ALIGN 32
+
+/* Queue Element Transfer Descriptor */
+#define EHCI_QTD_NBUFFERS 5
+typedef struct {
+ ehci_link_t qtd_next;
+ ehci_link_t qtd_altnext;
+ u_int32_t qtd_status;
+#define EHCI_QTD_GET_STATUS(x) (((x) >> 0) & 0xff)
+#define EHCI_QTD_SET_STATUS(x) ((x) << 0)
+#define EHCI_QTD_ACTIVE 0x80
+#define EHCI_QTD_HALTED 0x40
+#define EHCI_QTD_BUFERR 0x20
+#define EHCI_QTD_BABBLE 0x10
+#define EHCI_QTD_XACTERR 0x08
+#define EHCI_QTD_MISSEDMICRO 0x04
+#define EHCI_QTD_SPLITXSTATE 0x02
+#define EHCI_QTD_PINGSTATE 0x01
+#define EHCI_QTD_STATERRS 0x7c
+#define EHCI_QTD_GET_PID(x) (((x) >> 8) & 0x3)
+#define EHCI_QTD_SET_PID(x) ((x) << 8)
+#define EHCI_QTD_PID_OUT 0x0
+#define EHCI_QTD_PID_IN 0x1
+#define EHCI_QTD_PID_SETUP 0x2
+#define EHCI_QTD_GET_CERR(x) (((x) >> 10) & 0x3)
+#define EHCI_QTD_SET_CERR(x) ((x) << 10)
+#define EHCI_QTD_GET_C_PAGE(x) (((x) >> 12) & 0x7)
+#define EHCI_QTD_SET_C_PAGE(x) ((x) << 12)
+#define EHCI_QTD_GET_IOC(x) (((x) >> 15) & 0x1)
+#define EHCI_QTD_IOC 0x00008000
+#define EHCI_QTD_GET_BYTES(x) (((x) >> 16) & 0x7fff)
+#define EHCI_QTD_SET_BYTES(x) ((x) << 16)
+#define EHCI_QTD_GET_TOGGLE(x) (((x) >> 31) & 0x1)
+#define EHCI_QTD_SET_TOGGLE(x) ((x) << 31)
+#define EHCI_QTD_TOGGLE_MASK 0x80000000
+ ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS];
+ ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
+} ehci_qtd_t;
+
+#define EHCI_QTD_ALIGN 32
+
+/* Queue Head */
+typedef struct {
+ ehci_link_t qh_link;
+ u_int32_t qh_endp;
+#define EHCI_QH_GET_ADDR(x) (((x) >> 0) & 0x7f) /* endpoint addr */
+#define EHCI_QH_SET_ADDR(x) (x)
+#define EHCI_QH_ADDRMASK 0x0000007f
+#define EHCI_QH_GET_INACT(x) (((x) >> 7) & 0x01) /* inactivate on next */
+#define EHCI_QH_INACT 0x00000080
+#define EHCI_QH_GET_ENDPT(x) (((x) >> 8) & 0x0f) /* endpoint no */
+#define EHCI_QH_SET_ENDPT(x) ((x) << 8)
+#define EHCI_QH_GET_EPS(x) (((x) >> 12) & 0x03) /* endpoint speed */
+#define EHCI_QH_SET_EPS(x) ((x) << 12)
+#define EHCI_QH_SPEED_FULL 0x0
+#define EHCI_QH_SPEED_LOW 0x1
+#define EHCI_QH_SPEED_HIGH 0x2
+#define EHCI_QH_GET_DTC(x) (((x) >> 14) & 0x01) /* data toggle control */
+#define EHCI_QH_DTC 0x00004000
+#define EHCI_QH_GET_HRECL(x) (((x) >> 15) & 0x01) /* head of reclamation */
+#define EHCI_QH_HRECL 0x00008000
+#define EHCI_QH_GET_MPL(x) (((x) >> 16) & 0x7ff) /* max packet len */
+#define EHCI_QH_SET_MPL(x) ((x) << 16)
+#define EHCI_QH_MPLMASK 0x07ff0000
+#define EHCI_QH_GET_CTL(x) (((x) >> 27) & 0x01) /* control endpoint */
+#define EHCI_QH_CTL 0x08000000
+#define EHCI_QH_GET_NRL(x) (((x) >> 28) & 0x0f) /* NAK reload */
+#define EHCI_QH_SET_NRL(x) ((x) << 28)
+ u_int32_t qh_endphub;
+#define EHCI_QH_GET_SMASK(x) (((x) >> 0) & 0xff) /* intr sched mask */
+#define EHCI_QH_SET_SMASK(x) ((x) << 0)
+#define EHCI_QH_GET_CMASK(x) (((x) >> 8) & 0xff) /* split completion mask */
+#define EHCI_QH_SET_CMASK(x) ((x) << 8)
+#define EHCI_QH_GET_HUBA(x) (((x) >> 16) & 0x7f) /* hub address */
+#define EHCI_QH_SET_HUBA(x) ((x) << 16)
+#define EHCI_QH_GET_PORT(x) (((x) >> 23) & 0x7f) /* hub port */
+#define EHCI_QH_SET_PORT(x) ((x) << 23)
+#define EHCI_QH_GET_MULT(x) (((x) >> 30) & 0x03) /* pipe multiplier */
+#define EHCI_QH_SET_MULT(x) ((x) << 30)
+ ehci_link_t qh_curqtd;
+ ehci_qtd_t qh_qtd;
+} ehci_qh_t;
+
+#define EHCI_QH_ALIGN 32
+
+/* Periodic Frame Span Traversal Node */
+typedef struct {
+ ehci_link_t fstn_link;
+ ehci_link_t fstn_back;
+} ehci_fstn_t;
+
+#define EHCI_FSTN_ALIGN 32
+
+#endif /* _DEV_PCI_EHCIREG_H_ */
diff --git a/sys/mips/rmi/ehcivar.h b/sys/mips/rmi/ehcivar.h
new file mode 100644
index 0000000..b1b80be
--- /dev/null
+++ b/sys/mips/rmi/ehcivar.h
@@ -0,0 +1,195 @@
+/* $NetBSD: ehcivar.h,v 1.19 2005/04/29 15:04:29 augustss Exp $ */
+/* $FreeBSD: src/sys/dev/usb/ehcivar.h,v 1.9.2.1.8.1 2008/10/02 02:57:24 kensmith Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lennart@augustsson.net).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+typedef struct ehci_soft_qtd {
+ ehci_qtd_t qtd;
+ struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */
+ ehci_physaddr_t physaddr;
+ usbd_xfer_handle xfer;
+ LIST_ENTRY(ehci_soft_qtd) hnext;
+ u_int16_t len;
+} ehci_soft_qtd_t;
+
+#define EHCI_SQTD_SIZE ((sizeof (struct ehci_soft_qtd) + EHCI_QTD_ALIGN - 1) / EHCI_QTD_ALIGN * EHCI_QTD_ALIGN)
+#define EHCI_SQTD_CHUNK (EHCI_PAGE_SIZE / EHCI_SQTD_SIZE)
+
+typedef struct ehci_soft_qh {
+ ehci_qh_t qh;
+ struct ehci_soft_qh *next;
+ struct ehci_soft_qh *prev;
+ struct ehci_soft_qtd *sqtd;
+ ehci_physaddr_t physaddr;
+ int islot; /* Interrupt list slot. */
+} ehci_soft_qh_t;
+
+#define EHCI_SQH_SIZE ((sizeof (struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN)
+#define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE)
+
+struct ehci_xfer {
+ struct usbd_xfer xfer;
+ struct usb_task abort_task;
+ LIST_ENTRY(ehci_xfer) inext; /* list of active xfers */
+ ehci_soft_qtd_t *sqtdstart;
+ ehci_soft_qtd_t *sqtdend;
+ u_int32_t ehci_xfer_flags;
+#ifdef DIAGNOSTIC
+ int isdone;
+#endif
+};
+
+#define EHCI_XFER_ABORTING 0x0001 /* xfer is aborting. */
+#define EHCI_XFER_ABORTWAIT 0x0002 /* abort completion is being awaited. */
+
+#define EXFER(xfer) ((struct ehci_xfer *)(xfer))
+
+/*
+ * Information about an entry in the interrupt list.
+ */
+struct ehci_soft_islot {
+ ehci_soft_qh_t *sqh; /* Queue Head. */
+};
+
+#define EHCI_FRAMELIST_MAXCOUNT 1024
+#define EHCI_IPOLLRATES 8 /* Poll rates (1ms, 2, 4, 8 ... 128) */
+#define EHCI_INTRQHS ((1 << EHCI_IPOLLRATES) - 1)
+#define EHCI_MAX_POLLRATE (1 << (EHCI_IPOLLRATES - 1))
+#define EHCI_IQHIDX(lev, pos) \
+ ((((pos) & ((1 << (lev)) - 1)) | (1 << (lev))) - 1)
+#define EHCI_ILEV_IVAL(lev) (1 << (lev))
+
+#define EHCI_HASH_SIZE 128
+#define EHCI_COMPANION_MAX 8
+
+#define EHCI_SCFLG_DONEINIT 0x0001 /* ehci_init() has been called. */
+#define EHCI_SCFLG_LOSTINTRBUG 0x0002 /* workaround for VIA / ATI chipsets */
+
+typedef struct ehci_softc {
+ struct usbd_bus sc_bus; /* base device */
+ int sc_flags;
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
+ bus_size_t sc_size;
+#if defined(__FreeBSD__)
+ void *ih;
+
+ struct resource *io_res;
+ struct resource *irq_res;
+#endif
+ u_int sc_offs; /* offset to operational regs */
+
+ char sc_vendor[32]; /* vendor string for root hub */
+ int sc_id_vendor; /* vendor ID for root hub */
+
+ u_int32_t sc_cmd; /* shadow of cmd reg during suspend */
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ void *sc_powerhook; /* cookie from power hook */
+ void *sc_shutdownhook; /* cookie from shutdown hook */
+#endif
+
+ u_int sc_ncomp;
+ u_int sc_npcomp;
+ struct usbd_bus *sc_comps[EHCI_COMPANION_MAX];
+
+ usb_dma_t sc_fldma;
+ ehci_link_t *sc_flist;
+ u_int sc_flsize;
+#ifndef __FreeBSD__
+ u_int sc_rand; /* XXX need proper intr scheduling */
+#endif
+
+ struct ehci_soft_islot sc_islots[EHCI_INTRQHS];
+
+ LIST_HEAD(, ehci_xfer) sc_intrhead;
+
+ ehci_soft_qh_t *sc_freeqhs;
+ ehci_soft_qtd_t *sc_freeqtds;
+
+ int sc_noport;
+ u_int8_t sc_addr; /* device address */
+ u_int8_t sc_conf; /* device configuration */
+ usbd_xfer_handle sc_intrxfer;
+ char sc_isreset;
+#ifdef USB_USE_SOFTINTR
+ char sc_softwake;
+#endif /* USB_USE_SOFTINTR */
+
+ u_int32_t sc_eintrs;
+ ehci_soft_qh_t *sc_async_head;
+
+ SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
+
+ struct lock sc_doorbell_lock;
+
+ usb_callout_t sc_tmo_pcd;
+ usb_callout_t sc_tmo_intrlist;
+
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ device_ptr_t sc_child; /* /dev/usb# device */
+#endif
+ char sc_dying;
+#if defined(__NetBSD__)
+ struct usb_dma_reserve sc_dma_reserve;
+#endif
+} ehci_softc_t;
+
+#define EREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a))
+#define EREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a))
+#define EREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a))
+#define EWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x))
+#define EWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x))
+#define EWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x))
+#define EOREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
+#define EOREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
+#define EOREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
+#define EOWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
+#define EOWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
+#define EOWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
+
+usbd_status ehci_init(ehci_softc_t *);
+int ehci_intr(void *);
+int ehci_detach(ehci_softc_t *, int);
+
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+int ehci_activate(device_ptr_t, enum devact);
+
+#endif
+void ehci_power(int state, void *priv);
+void ehci_shutdown(void *v);
+
+#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
diff --git a/sys/mips/rmi/files.xlr b/sys/mips/rmi/files.xlr
new file mode 100644
index 0000000..e2ed518
--- /dev/null
+++ b/sys/mips/rmi/files.xlr
@@ -0,0 +1,26 @@
+# $FreeBSD$
+#mips/rmi/xlr_boot1_console.c standard
+mips/rmi/xlr_machdep.c standard
+mips/rmi/clock.c standard
+mips/rmi/tick.c standard
+mips/rmi/iodi.c standard
+mips/rmi/msgring.c standard
+mips/rmi/msgring_xls.c standard
+mips/rmi/board.c standard
+mips/rmi/on_chip.c standard
+mips/rmi/intr_machdep.c standard
+mips/rmi/xlr_i2c.c optional iic
+mips/rmi/uart_bus_xlr_iodi.c optional uart
+mips/rmi/uart_cpu_mips_xlr.c optional uart
+mips/rmi/perfmon_kern.c optional xlr_perfmon
+mips/rmi/perfmon_percpu.c optional xlr_perfmon
+#mips/rmi/pcibus.c optional pci
+#mips/rmi/xlr_pci.c optional pci
+#mips/rmi/xls_ehci.c optional usb ehci
+dev/rmi/xlr/rge.c optional rge
+mips/rmi/bus_space_rmi.c standard
+dev/iicbus/xlr_rtc.c optional xlr_rtc
+dev/iicbus/xlr_temperature.c optional xlr_temperature
+dev/iicbus/xlr_eeprom.c optional xlr_eeprom
+dev/rmi/sec/rmisec.c optional rmisec
+dev/rmi/sec/rmilib.c optional rmisec
diff --git a/sys/mips/rmi/interrupt.h b/sys/mips/rmi/interrupt.h
new file mode 100644
index 0000000..013a8e9
--- /dev/null
+++ b/sys/mips/rmi/interrupt.h
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#ifndef _RMI_INTERRUPT_H_
+#define _RMI_INTERRUPT_H_
+
+/* Defines for the IRQ numbers */
+
+#define IRQ_DUMMY_UART 2
+#define IRQ_IPI_SMP_FUNCTION 3
+#define IRQ_IPI_SMP_RESCHEDULE 4
+#define IRQ_REMOTE_DEBUG 5
+#define IRQ_MSGRING 6
+#define IRQ_TIMER 7
+
+#endif /* _RMI_INTERRUPT_H_ */
diff --git a/sys/mips/rmi/intr_machdep.c b/sys/mips/rmi/intr_machdep.c
new file mode 100644
index 0000000..dc34fda
--- /dev/null
+++ b/sys/mips/rmi/intr_machdep.c
@@ -0,0 +1,217 @@
+/*-
+ * Copyright (c) 2006-2009 RMI Corporation
+ * Copyright (c) 2002-2004 Juli Mallett <jmallett@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/cpuinfo.h>
+#include <machine/cpuregs.h>
+#include <machine/frame.h>
+#include <machine/intr_machdep.h>
+#include <machine/md_var.h>
+#include <machine/trap.h>
+#include <machine/hwfunc.h>
+#include <mips/rmi/xlrconfig.h>
+#include <mips/rmi/interrupt.h>
+#include <mips/rmi/clock.h>
+#include <mips/rmi/pic.h>
+
+/*#include <machine/intrcnt.h>*/
+static mips_intrcnt_t mips_intr_counters[XLR_MAX_INTR];
+struct mips_intrhand mips_intr_handlers[XLR_MAX_INTR];
+static int intrcnt_index;
+
+static void
+mips_mask_hard_irq(void *source)
+{
+ uintptr_t irq = (uintptr_t) source;
+
+ write_c0_eimr64(read_c0_eimr64() & ~(1ULL << irq));
+}
+
+static void
+mips_unmask_hard_irq(void *source)
+{
+ uintptr_t irq = (uintptr_t) source;
+
+ write_c0_eimr64(read_c0_eimr64() | (1ULL << irq));
+}
+
+void
+cpu_establish_hardintr(const char *name, driver_filter_t * filt,
+ void (*handler) (void *), void *arg, int irq, int flags, void **cookiep)
+{
+ struct mips_intrhand *mih; /* descriptor for the IRQ */
+ struct intr_event *ie; /* descriptor for the IRQ */
+ int errcode;
+
+ if (irq < 0 || irq > XLR_MAX_INTR)
+ panic("%s called for unknown hard intr %d", __func__, irq);
+
+ /*
+ * FIXME locking - not needed now, because we do this only on
+ * startup from CPU0
+ */
+ mih = &mips_intr_handlers[irq];
+ /* mih->cntp = &intrcnt[irq]; */
+ ie = mih->mih_event;
+ if (ie == NULL) {
+ errcode = intr_event_create(&ie, (void *)(uintptr_t) irq, 0,
+ irq, mips_mask_hard_irq, mips_unmask_hard_irq,
+ NULL, NULL, "hard intr%d:", irq);
+
+ if (errcode) {
+ printf("Could not create event for intr %d\n", irq);
+ return;
+ }
+ }
+ intr_event_add_handler(ie, name, filt, handler, arg,
+ intr_priority(flags), flags, cookiep);
+ mih->mih_event = ie;
+ mips_unmask_hard_irq((void *)(uintptr_t) irq);
+}
+
+
+void
+cpu_establish_softintr(const char *name, driver_filter_t * filt,
+ void (*handler) (void *), void *arg, int irq, int flags,
+ void **cookiep)
+{
+ /* we don't separate them into soft/hard like other mips */
+ cpu_establish_hardintr(name, filt, handler, arg, irq, flags, cookiep);
+}
+
+void
+cpu_intr(struct trapframe *tf)
+{
+ struct mips_intrhand *mih;
+ struct intr_event *ie;
+ register_t eirr;
+ int i;
+
+ critical_enter();
+ eirr = read_c0_eirr64();
+ if (eirr == 0) {
+ critical_exit();
+ return;
+ }
+ /*
+ * No need to clear the EIRR here. the handler is gonna write to
+ * compare which clears eirr also
+ */
+ if (eirr & (1 << IRQ_TIMER)) {
+ count_compare_clockhandler(tf);
+ critical_exit();
+ return;
+ }
+
+ /* FIXME sched pin >? LOCK>? */
+ for (i = sizeof(eirr) * 8 - 1; i >= 0; i--) {
+ if ((eirr & (1ULL << i)) == 0)
+ continue;
+#ifdef SMP
+ /* These are reserved interrupts */
+ if ((i == IPI_AST) || (i == IPI_RENDEZVOUS) || (i == IPI_STOP)
+ || (i == IPI_SMP_CALL_FUNCTION)) {
+ write_c0_eirr64(1ULL << i);
+ pic_ack(i);
+ smp_handle_ipi(tf, i);
+ pic_delayed_ack(i);
+ continue;
+ }
+#ifdef XLR_PERFMON
+ if (i == IPI_PERFMON) {
+ write_c0_eirr64(1ULL << i);
+ pic_ack(i);
+ xlr_perfmon_sampler(NULL);
+ pic_delayed_ack(i);
+ continue;
+ }
+#endif
+#endif
+ mih = &mips_intr_handlers[i];
+ /* atomic_add_long(mih->cntp, 1); */
+ ie = mih->mih_event;
+
+ write_c0_eirr64(1ULL << i);
+ pic_ack(i);
+ if (!ie || TAILQ_EMPTY(&ie->ie_handlers)) {
+ printf("stray interrupt %d\n", i);
+ continue;
+ }
+ if (intr_event_handle(ie, tf) != 0) {
+ printf("stray interrupt %d\n", i);
+ }
+ pic_delayed_ack(i);
+ }
+ critical_exit();
+}
+
+void
+mips_intrcnt_setname(mips_intrcnt_t counter, const char *name)
+{
+ int idx = counter - intrcnt;
+
+ KASSERT(counter != NULL, ("mips_intrcnt_setname: NULL counter"));
+
+ snprintf(intrnames + (MAXCOMLEN + 1) * idx,
+ MAXCOMLEN + 1, "%-*s", MAXCOMLEN, name);
+}
+
+mips_intrcnt_t
+mips_intrcnt_create(const char* name)
+{
+ mips_intrcnt_t counter = &intrcnt[intrcnt_index++];
+
+ mips_intrcnt_setname(counter, name);
+ return counter;
+}
+
+void
+cpu_init_interrupts()
+{
+ int i;
+ char name[MAXCOMLEN + 1];
+
+ /*
+ * Initialize all available vectors so spare IRQ
+ * would show up in systat output
+ */
+ for (i = 0; i < XLR_MAX_INTR; i++) {
+ snprintf(name, MAXCOMLEN + 1, "int%d:", i);
+ mips_intr_counters[i] = mips_intrcnt_create(name);
+ }
+}
diff --git a/sys/mips/rmi/iodi.c b/sys/mips/rmi/iodi.c
new file mode 100644
index 0000000..0983fe7
--- /dev/null
+++ b/sys/mips/rmi/iodi.c
@@ -0,0 +1,308 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+
+#define __RMAN_RESOURCE_VISIBLE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/reboot.h>
+#include <sys/types.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/module.h>
+
+#include <machine/cpu.h>
+#include <machine/bus.h>
+#include <machine/bus.h>
+#include <machine/intr_machdep.h>
+#include <mips/rmi/iomap.h>
+#include <mips/rmi/pic.h>
+#include <mips/rmi/shared_structs.h>
+#include <mips/rmi/board.h>
+#include <sys/rman.h>
+
+
+#include <machine/param.h>
+#include <machine/intr_machdep.h>
+#include <machine/clock.h> /* for DELAY */
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <mips/rmi/interrupt.h>
+#include <mips/rmi/msgring.h>
+#include <mips/rmi/iomap.h>
+#include <mips/rmi/debug.h>
+#include <mips/rmi/pic.h>
+#include <mips/rmi/xlrconfig.h>
+#include <mips/rmi/shared_structs.h>
+#include <mips/rmi/board.h>
+
+#include <dev/rmi/xlr/atx_cpld.h>
+#include <dev/rmi/xlr/xgmac_mdio.h>
+
+extern void iodi_activateirqs(void);
+
+extern bus_space_tag_t uart_bus_space_mem;
+
+static struct resource *
+iodi_alloc_resource(device_t, device_t, int, int *,
+ u_long, u_long, u_long, u_int);
+
+static int
+iodi_activate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int
+iodi_setup_intr(device_t, device_t, struct resource *, int,
+ driver_filter_t *, driver_intr_t *, void *, void **);
+
+struct iodi_softc *iodi_softc; /* There can be only one. */
+
+/*
+static void pic_usb_ack(void *arg)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+ int irq = PIC_USB_IRQ ;
+
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
+ mtx_unlock_spin(&xlr_pic_lock);
+}
+*/
+
+
+static int
+iodi_setup_intr(device_t dev, device_t child,
+ struct resource *ires, int flags, driver_filter_t * filt, driver_intr_t * intr, void *arg,
+ void **cookiep)
+{
+ int level;
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+ xlr_reg_t reg;
+
+ /* FIXME is this the right place to fiddle with PIC? */
+ if (strcmp(device_get_name(child), "uart") == 0) {
+ /* FIXME uart 1? */
+ if (rmi_spin_mutex_safe)
+ mtx_lock_spin(&xlr_pic_lock);
+ level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_UART_0_INDEX);
+ xlr_write_reg(mmio, PIC_IRT_0_UART_0, 0x01);
+ xlr_write_reg(mmio, PIC_IRT_1_UART_0, ((1 << 31) | (level << 30) | (1 << 6) | (PIC_UART_0_IRQ)));
+ if (rmi_spin_mutex_safe)
+ mtx_unlock_spin(&xlr_pic_lock);
+ cpu_establish_hardintr("uart", filt,
+ (driver_intr_t *) intr, (void *)arg, PIC_UART_0_IRQ, flags, cookiep);
+
+ } else if (strcmp(device_get_name(child), "rge") == 0) {
+ int irq;
+
+ /* This is a hack to pass in the irq */
+ irq = (int)ires->__r_i;
+ if (rmi_spin_mutex_safe)
+ mtx_lock_spin(&xlr_pic_lock);
+ reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE);
+ xlr_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31));
+ if (rmi_spin_mutex_safe)
+ mtx_unlock_spin(&xlr_pic_lock);
+ cpu_establish_hardintr("rge", filt, (driver_intr_t *) intr, (void *)arg, irq, flags, cookiep);
+
+ } else if (strcmp(device_get_name(child), "ehci") == 0) {
+ if (rmi_spin_mutex_safe)
+ mtx_lock_spin(&xlr_pic_lock);
+ reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE);
+ xlr_write_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31));
+ if (rmi_spin_mutex_safe)
+ mtx_unlock_spin(&xlr_pic_lock);
+ cpu_establish_hardintr("ehci", filt, (driver_intr_t *) intr, (void *)arg, PIC_USB_IRQ, flags, cookiep);
+ }
+ /*
+ * This causes a panic and looks recursive to me (RRS).
+ * BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt,
+ * intr, arg, cookiep);
+ */
+
+ return (0);
+}
+
+/* Strange hook found in mips/include/bus.h */
+#ifndef MIPS_BUS_SPACE_PCI
+#define MIPS_BUS_SPACE_PCI 10
+#endif
+
+static struct resource *
+iodi_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct resource *res = malloc(sizeof(*res), M_DEVBUF, M_WAITOK);
+ int unit;
+
+#ifdef DEBUG
+ switch (type) {
+ case SYS_RES_IRQ:
+ device_printf(bus, "IRQ resource - for %s %lx-%lx\n",
+ device_get_nameunit(child), start, end);
+ break;
+
+ case SYS_RES_IOPORT:
+ device_printf(bus, "IOPORT resource - for %s %lx-%lx\n",
+ device_get_nameunit(child), start, end);
+ break;
+
+ case SYS_RES_MEMORY:
+ device_printf(bus, "MEMORY resource - for %s %lx-%lx\n",
+ device_get_nameunit(child), start, end);
+ break;
+ }
+#endif
+
+ if (strcmp(device_get_name(child), "uart") == 0) {
+ if ((unit = device_get_unit(child)) == 0) { /* uart 0 */
+ res->r_bushandle = (xlr_io_base + XLR_IO_UART_0_OFFSET);
+ } else if (unit == 1) {
+ res->r_bushandle = (xlr_io_base + XLR_IO_UART_1_OFFSET);
+ } else
+ printf("%s: Unknown uart unit\n", __FUNCTION__);
+
+ res->r_bustag = uart_bus_space_mem;
+ } else if (strcmp(device_get_name(child), "ehci") == 0) {
+ res->r_bushandle = 0xbef24000;
+ res->r_bustag = (bus_space_tag_t) MIPS_BUS_SPACE_PCI;
+ } else if (strcmp(device_get_name(child), "cfi") == 0) {
+ res->r_bushandle = 0xbc000000;
+ res->r_bustag = 0;
+ }
+ /* res->r_start = *rid; */
+ return (res);
+}
+
+static int
+iodi_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (0);
+}
+
+/* prototypes */
+static int iodi_probe(device_t);
+static int iodi_attach(device_t);
+static void iodi_identify(driver_t *, device_t);
+
+int
+iodi_probe(device_t dev)
+{
+ return 0;
+}
+
+void
+iodi_identify(driver_t * driver, device_t parent)
+{
+
+ BUS_ADD_CHILD(parent, 0, "iodi", 0);
+}
+
+int
+iodi_attach(device_t dev)
+{
+ device_t tmpd;
+
+ /*
+ * Attach each devices
+ */
+ device_add_child(dev, "uart", 0);
+ device_add_child(dev, "xlr_i2c", 0);
+
+ if (xlr_board_info.usb)
+ device_add_child(dev, "ehci", 0);
+
+ if (xlr_board_info.cfi)
+ device_add_child(dev, "cfi", 0);
+
+ if (xlr_board_info.gmac_block[0].enabled) {
+ tmpd = device_add_child(dev, "rge", 0);
+ device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
+
+ tmpd = device_add_child(dev, "rge", 1);
+ device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
+
+ tmpd = device_add_child(dev, "rge", 2);
+ device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
+
+ tmpd = device_add_child(dev, "rge", 3);
+ device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
+ }
+ if (xlr_board_info.gmac_block[1].enabled) {
+ if (xlr_board_info.gmac_block[1].type == XLR_GMAC) {
+ tmpd = device_add_child(dev, "rge", 4);
+ device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
+
+ tmpd = device_add_child(dev, "rge", 5);
+ device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
+
+ tmpd = device_add_child(dev, "rge", 6);
+ device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
+
+ tmpd = device_add_child(dev, "rge", 7);
+ device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
+ } else if (xlr_board_info.gmac_block[1].type == XLR_XGMAC) {
+#if 0 /* XGMAC not yet */
+ tmpd = device_add_child(dev, "rge", 4);
+ device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
+
+ tmpd = device_add_child(dev, "rge", 5);
+ device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
+#endif
+ } else
+ device_printf(dev, "Unknown type of gmac 1\n");
+ }
+ bus_generic_probe(dev);
+ bus_generic_attach(dev);
+ return 0;
+}
+
+static device_method_t iodi_methods[] = {
+ DEVMETHOD(device_probe, iodi_probe),
+ DEVMETHOD(device_attach, iodi_attach),
+ DEVMETHOD(device_identify, iodi_identify),
+ DEVMETHOD(bus_alloc_resource, iodi_alloc_resource),
+ DEVMETHOD(bus_activate_resource, iodi_activate_resource),
+ DEVMETHOD(bus_setup_intr, iodi_setup_intr),
+ {0, 0},
+};
+
+static driver_t iodi_driver = {
+ "iodi",
+ iodi_methods,
+ 1 /* no softc */
+};
+static devclass_t iodi_devclass;
+
+DRIVER_MODULE(iodi, nexus, iodi_driver, iodi_devclass, 0, 0);
diff --git a/sys/mips/rmi/iomap.h b/sys/mips/rmi/iomap.h
new file mode 100644
index 0000000..afc52bf
--- /dev/null
+++ b/sys/mips/rmi/iomap.h
@@ -0,0 +1,113 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#ifndef _RMI_IOMAP_H_
+#define _RMI_IOMAP_H_
+
+#include <machine/endian.h>
+#define XLR_DEVICE_REGISTER_BASE 0x1EF00000
+#define DEFAULT_XLR_IO_BASE 0xffffffffbef00000ULL
+#define XLR_IO_SIZE 0x1000
+
+#define XLR_IO_BRIDGE_OFFSET 0x00000
+
+#define XLR_IO_DDR2_CHN0_OFFSET 0x01000
+#define XLR_IO_DDR2_CHN1_OFFSET 0x02000
+#define XLR_IO_DDR2_CHN2_OFFSET 0x03000
+#define XLR_IO_DDR2_CHN3_OFFSET 0x04000
+
+#define XLR_IO_RLD2_CHN0_OFFSET 0x05000
+#define XLR_IO_RLD2_CHN1_OFFSET 0x06000
+
+#define XLR_IO_SRAM_OFFSET 0x07000
+
+#define XLR_IO_PIC_OFFSET 0x08000
+#define XLR_IO_PCIX_OFFSET 0x09000
+#define XLR_IO_HT_OFFSET 0x0A000
+
+#define XLR_IO_SECURITY_OFFSET 0x0B000
+
+#define XLR_IO_GMAC_0_OFFSET 0x0C000
+#define XLR_IO_GMAC_1_OFFSET 0x0D000
+#define XLR_IO_GMAC_2_OFFSET 0x0E000
+#define XLR_IO_GMAC_3_OFFSET 0x0F000
+
+#define XLR_IO_SPI4_0_OFFSET 0x10000
+#define XLR_IO_XGMAC_0_OFFSET 0x11000
+#define XLR_IO_SPI4_1_OFFSET 0x12000
+#define XLR_IO_XGMAC_1_OFFSET 0x13000
+
+#define XLR_IO_UART_0_OFFSET 0x14000
+#define XLR_IO_UART_1_OFFSET 0x15000
+#define XLR_UART0ADDR (XLR_IO_UART_0_OFFSET+XLR_DEVICE_REGISTER_BASE)
+
+
+
+#define XLR_IO_I2C_0_OFFSET 0x16000
+#define XLR_IO_I2C_1_OFFSET 0x17000
+
+#define XLR_IO_GPIO_OFFSET 0x18000
+
+#define XLR_IO_FLASH_OFFSET 0x19000
+
+#define XLR_IO_TB_OFFSET 0x1C000
+
+#define XLR_IO_GMAC_4_OFFSET 0x20000
+#define XLR_IO_GMAC_5_OFFSET 0x21000
+#define XLR_IO_GMAC_6_OFFSET 0x22000
+#define XLR_IO_GMAC_7_OFFSET 0x23000
+
+#define XLR_IO_PCIE_0_OFFSET 0x1E000
+#define XLR_IO_PCIE_1_OFFSET 0x1F000
+
+#define XLR_IO_USB_0_OFFSET 0x24000
+#define XLR_IO_USB_1_OFFSET 0x25000
+
+#define XLR_IO_COMP_OFFSET 0x1d000
+
+/* Base Address (Virtual) of the PCI Config address space
+ * For now, choose 256M phys in kseg1 = 0xA0000000 + (1<<28)
+ * Config space spans 256 (num of buses) * 256 (num functions) * 256 bytes
+ * ie 1<<24 = 16M
+ */
+#define DEFAULT_PCI_CONFIG_BASE 0x18000000
+#define DEFAULT_HT_TYPE0_CFG_BASE 0x16000000
+#define DEFAULT_HT_TYPE1_CFG_BASE 0x17000000
+
+typedef volatile __uint32_t xlr_reg_t;
+extern unsigned long xlr_io_base;
+
+#define xlr_io_mmio(offset) ((xlr_reg_t *)(xlr_io_base+(offset)))
+
+#define xlr_read_reg(base, offset) (__ntohl((base)[(offset)]))
+#define xlr_write_reg(base, offset, value) ((base)[(offset)] = __htonl((value)))
+
+extern void on_chip_init(void);
+
+#endif /* _RMI_IOMAP_H_ */
diff --git a/sys/mips/rmi/msgring.c b/sys/mips/rmi/msgring.c
new file mode 100644
index 0000000..77d964c
--- /dev/null
+++ b/sys/mips/rmi/msgring.c
@@ -0,0 +1,317 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+/**********************************************************
+ * -----------------DO NOT EDIT THIS FILE------------------
+ * This file has been autogenerated by the build process
+ * from "msgring.cfg"
+ **********************************************************/
+
+#include <mips/rmi/msgring.h>
+
+struct bucket_size bucket_sizes = {
+ {
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 0,
+ 32, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 0,
+ 0, 32, 32, 32, 32, 32, 0, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 32, 0, 32, 0, 0, 0, 0,
+ 128, 0, 0, 0, 128, 0, 0, 0,
+ }
+};
+
+struct stn_cc cc_table_cpu_0 = {{
+
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 4, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {0, 2, 4, 4, 4, 4, 0, 2},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 2, 0, 2, 0, 0, 0, 0},
+ {16, 0, 0, 0, 16, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_cpu_1 = {{
+
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {0, 2, 4, 4, 4, 4, 0, 2},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 2, 0, 2, 0, 0, 0, 0},
+ {16, 0, 0, 0, 16, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_cpu_2 = {{
+
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {0, 4, 4, 4, 4, 4, 0, 4},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 0, 4, 0, 0, 0, 0},
+ {16, 0, 0, 0, 16, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_cpu_3 = {{
+
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {0, 4, 4, 4, 4, 4, 0, 4},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 0, 4, 0, 0, 0, 0},
+ {16, 0, 0, 0, 16, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_cpu_4 = {{
+
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {0, 4, 4, 4, 4, 4, 0, 4},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 0, 4, 0, 0, 0, 0},
+ {16, 0, 0, 0, 16, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_cpu_5 = {{
+
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {0, 4, 4, 4, 4, 4, 0, 4},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 0, 4, 0, 0, 0, 0},
+ {16, 0, 0, 0, 16, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_cpu_6 = {{
+
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {0, 4, 4, 4, 4, 4, 0, 4},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 0, 4, 0, 0, 0, 0},
+ {16, 0, 0, 0, 16, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_cpu_7 = {{
+
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {4, 2, 2, 2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2, 2, 2, 0},
+ {0, 4, 4, 4, 4, 4, 0, 4},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 0, 4, 0, 0, 0, 0},
+ {16, 0, 0, 0, 16, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_xgs_0 = {{
+
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_xgs_1 = {{
+
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 4, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_gmac = {{
+
+ {8, 8, 8, 8, 16, 16, 16, 16},
+ {8, 8, 8, 8, 16, 16, 16, 16},
+ {8, 8, 8, 8, 16, 16, 16, 16},
+ {8, 8, 8, 8, 16, 16, 16, 16},
+ {8, 8, 8, 8, 16, 16, 16, 16},
+ {8, 8, 8, 8, 16, 16, 16, 16},
+ {8, 8, 8, 8, 16, 16, 16, 16},
+ {8, 8, 8, 8, 16, 16, 16, 16},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 0, 0, 0, 0, 0, 4},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_dma = {{
+
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc cc_table_sec = {{
+
+ {8, 8, 8, 8, 0, 0, 0, 0},
+ {8, 8, 8, 4, 0, 0, 0, 0},
+ {8, 8, 8, 8, 0, 0, 0, 0},
+ {8, 8, 8, 8, 0, 0, 0, 0},
+ {8, 8, 8, 8, 0, 0, 0, 0},
+ {8, 8, 8, 8, 0, 0, 0, 0},
+ {8, 8, 8, 8, 0, 0, 0, 0},
+ {8, 8, 8, 8, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+}};
diff --git a/sys/mips/rmi/msgring.cfg b/sys/mips/rmi/msgring.cfg
new file mode 100644
index 0000000..cf9ea54
--- /dev/null
+++ b/sys/mips/rmi/msgring.cfg
@@ -0,0 +1,1182 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+/*
+ * This file defines the message ring configuration for phoenix-8. It tries to allow
+ * many different point-point communications between the message stations on the message ring
+ * and as result is _not_ the best configuration for performance
+ *
+ * The message ring on phoenix family of processors connects the cpus, gmacs, xgmac/spi4,
+ * security engine and the general purpose DMA engines. It provides a high bandwidth,
+ * low latency communication links. On traditional processors, this communication goes through
+ * which inherently does not scale very well with increasing number of cpus.
+ *
+ * Message ring has an in-built flow control mechanism. Every agent/station on the ring has to
+ * have software configured credits to send messages to any agent. Every receiving agent on the
+ * ring has a 256 entry FIFO that can divided into "buckets". All addressing on the ring is
+ * in terms of buckets. There are a total 128 buckets on the ring. The total number of credits
+ * across all sending agents should not exceed the bucket size.
+ *
+ * Below are the receiving agents and the max number of buckets they can have
+ * CPU 0 : 8 buckets
+ * CPU 1 : 8 buckets
+ * CPU 2 : 8 buckets
+ * CPU 3 : 8 buckets
+ * CPU 4 : 8 buckets
+ * CPU 5 : 8 buckets
+ * CPU 6 : 8 buckets
+ * CPU 7 : 8 buckets
+ *
+ * XGMAC 0 / SPI4 0
+ * TX : 16 buckets
+ * FREE : 2 buckets
+ * XGMAC 1 / SPI4 1
+ * TX : 16 buckets
+ * FREE : 2 buckets
+ *
+ * GMAC : 8 buckets
+ *
+ * SEC : 8 buckets
+ *
+ * DMA : 8 buckets
+ *
+ * The bucket size of a bucket should be aligned to the bucket's starting index in that
+ * receiving station's FIFO. For example, if sizes of bucket0 and bucket1 of a station
+ * are 32 and 32, bucket2's size has to be 64. bucket size 0 is valid.
+ *
+ * The format of the file is pretty straight forward. Each bucket definition has the size
+ * and the list of sending agents to that bucket with the number of credits to send.
+ *
+ * Undefined buckets have a size of 0 and Tx stations have 0 credits to send to that bucket.
+ *
+ * Following are the currently supported bucket names
+ * cpu_0_0
+ * cpu_0_1
+ * cpu_0_2
+ * cpu_0_3
+ * cpu_0_4
+ * cpu_0_5
+ * cpu_0_6
+ * cpu_0_7
+ *
+ * cpu_1_0
+ * cpu_1_1
+ * cpu_1_2
+ * cpu_1_3
+ * cpu_1_4
+ * cpu_1_5
+ * cpu_1_6
+ * cpu_1_7
+ *
+ * cpu_2_0
+ * cpu_2_1
+ * cpu_2_2
+ * cpu_2_3
+ * cpu_2_4
+ * cpu_2_5
+ * cpu_2_6
+ * cpu_2_7
+ *
+ * cpu_3_0
+ * cpu_3_1
+ * cpu_3_2
+ * cpu_3_3
+ * cpu_3_4
+ * cpu_3_5
+ * cpu_3_6
+ * cpu_3_7
+ *
+ * cpu_4_0
+ * cpu_4_1
+ * cpu_4_2
+ * cpu_4_3
+ * cpu_4_4
+ * cpu_4_5
+ * cpu_4_6
+ * cpu_4_7
+ *
+ * cpu_5_0
+ * cpu_5_1
+ * cpu_5_2
+ * cpu_5_3
+ * cpu_5_4
+ * cpu_5_5
+ * cpu_5_6
+ * cpu_5_7
+ *
+ * cpu_6_0
+ * cpu_6_1
+ * cpu_6_2
+ * cpu_6_3
+ * cpu_6_4
+ * cpu_6_5
+ * cpu_6_6
+ * cpu_6_7
+ *
+ * cpu_7_0
+ * cpu_7_1
+ * cpu_7_2
+ * cpu_7_3
+ * cpu_7_4
+ * cpu_7_5
+ * cpu_7_6
+ * cpu_7_7
+ *
+ * xgs_0_tx_0
+ * xgs_0_tx_1
+ * xgs_0_tx_2
+ * xgs_0_tx_3
+ * xgs_0_tx_4
+ * xgs_0_tx_5
+ * xgs_0_tx_6
+ * xgs_0_tx_7
+ * xgs_0_tx_8
+ * xgs_0_tx_9
+ * xgs_0_tx_10
+ * xgs_0_tx_11
+ * xgs_0_tx_12
+ * xgs_0_tx_13
+ * xgs_0_tx_14
+ * xgs_0_tx_15
+ *
+ * xgs_1_tx_0
+ * xgs_1_tx_1
+ * xgs_1_tx_2
+ * xgs_1_tx_3
+ * xgs_1_tx_4
+ * xgs_1_tx_5
+ * xgs_1_tx_6
+ * xgs_1_tx_7
+ * xgs_1_tx_8
+ * xgs_1_tx_9
+ * xgs_1_tx_10
+ * xgs_1_tx_11
+ * xgs_1_tx_12
+ * xgs_1_tx_13
+ * xgs_1_tx_14
+ * xgs_1_tx_15
+ *
+ * gmac_rsvd_0
+ * gmac_rfr_0
+ * gmac_tx_0
+ * gmac_tx_1
+ * gmac_tx_2
+ * gmac_tx_3
+ * gmac_rsvd_1
+ * gmac_rfr_1
+ *
+ * xgs_0_rsvd
+ * xgs_0_rfr
+ *
+ * xgs_1_rsvd
+ * xgs_1_rfr
+ *
+ * sec_pipe_0
+ * sec_pipe_1
+ * sec_pipe_2
+ * sec_pipe_3
+ * sec_rsa
+ *
+ * Following are the currently supported Tx Agent/Station names
+ *
+ * tx_stn_cpu_0
+ * tx_stn_cpu_1
+ * tx_stn_cpu_2
+ * tx_stn_cpu_3
+ * tx_stn_cpu_4
+ * tx_stn_cpu_5
+ * tx_stn_cpu_6
+ * tx_stn_cpu_7
+ *
+ * tx_stn_xgs_0
+ * tx_stn_xgs_1
+ *
+ * tx_stn_gmac
+ *
+ * tx_stn_dma
+ *
+ * tx_stn_sec
+ *
+ *
+ *
+ */
+
+/*************************************************************/
+// CPU_0 Message Station
+
+bucket "cpu_0_0" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_0_1" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_0_2" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_0_3" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_0_4" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_0_5" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_0_6" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_0_7" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+
+/*************************************************************/
+// CPU_1 Message Station
+
+bucket "cpu_1_0" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_1_1" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_1_2" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_1_3" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 4;
+ "tx_stn_cpu_0" 4; /* NEEDED BY RMIOS IPSEC */
+}
+bucket "cpu_1_4" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_1_5" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_1_6" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_1_7" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+
+/*************************************************************/
+// CPU_2 Message Station
+
+bucket "cpu_2_0" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_2_1" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_2_2" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_2_3" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_2_4" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_2_5" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_2_6" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_2_7" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+
+/*************************************************************/
+// CPU_3 Message Station
+
+bucket "cpu_3_0" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_3_1" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_3_2" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_3_3" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_3_4" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_3_5" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_3_6" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_3_7" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+
+/*************************************************************/
+// CPU_4 Message Station
+
+bucket "cpu_4_0" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_4_1" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_4_2" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_4_3" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_4_4" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_4_5" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_4_6" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_4_7" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+
+/*************************************************************/
+// CPU_5 Message Station
+
+bucket "cpu_5_0" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_5_1" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_5_2" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_5_3" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_5_4" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_5_5" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_5_6" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_5_7" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+
+
+/*************************************************************/
+// CPU_6 Message Station
+
+bucket "cpu_6_0" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_6_1" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_6_2" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_6_3" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_6_4" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_6_5" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_6_6" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_6_7" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+
+
+/*************************************************************/
+// CPU_7 Message Station
+
+bucket "cpu_7_0" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_7_1" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_7_2" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_7_3" {
+ size 32;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+ "tx_stn_gmac" 8;
+ "tx_stn_sec" 8;
+}
+bucket "cpu_7_4" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_7_5" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_7_6" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+bucket "cpu_7_7" {
+ size 32;
+ "tx_stn_gmac" 16;
+ "tx_stn_xgs_0" 8;
+ "tx_stn_xgs_1" 8;
+}
+
+
+/*************************************************************/
+// GMAC Message Station
+
+bucket "gmac_rfr_0" {
+ size 32;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_cpu_4" 4;
+ "tx_stn_cpu_5" 4;
+ "tx_stn_cpu_6" 4;
+ "tx_stn_cpu_7" 4;
+ "tx_stn_gmac" 4;
+}
+
+bucket "gmac_tx_0" {
+ size 32;
+ "tx_stn_cpu_0" 4;
+ "tx_stn_cpu_1" 4;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_cpu_4" 4;
+ "tx_stn_cpu_5" 4;
+ "tx_stn_cpu_6" 4;
+ "tx_stn_cpu_7" 4;
+}
+
+bucket "gmac_tx_1" {
+ size 32;
+ "tx_stn_cpu_0" 4;
+ "tx_stn_cpu_1" 4;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_cpu_4" 4;
+ "tx_stn_cpu_5" 4;
+ "tx_stn_cpu_6" 4;
+ "tx_stn_cpu_7" 4;
+}
+
+bucket "gmac_tx_2" {
+ size 32;
+ "tx_stn_cpu_0" 4;
+ "tx_stn_cpu_1" 4;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_cpu_4" 4;
+ "tx_stn_cpu_5" 4;
+ "tx_stn_cpu_6" 4;
+ "tx_stn_cpu_7" 4;
+}
+
+bucket "gmac_tx_3" {
+ size 32;
+ "tx_stn_cpu_0" 4;
+ "tx_stn_cpu_1" 4;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_cpu_4" 4;
+ "tx_stn_cpu_5" 4;
+ "tx_stn_cpu_6" 4;
+ "tx_stn_cpu_7" 4;
+}
+
+bucket "gmac_rfr_1" {
+ size 32;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_cpu_4" 4;
+ "tx_stn_cpu_5" 4;
+ "tx_stn_cpu_6" 4;
+ "tx_stn_cpu_7" 4;
+ "tx_stn_gmac" 4;
+}
+/*********************************************/
+// xgmac
+bucket "xgs_0_rfr" {
+ size 32;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_cpu_4" 4;
+ "tx_stn_cpu_5" 4;
+ "tx_stn_cpu_6" 4;
+ "tx_stn_cpu_7" 4;
+ "tx_stn_xgs_0" 4;
+}
+
+bucket "xgs_0_tx_0" {
+ size 32;
+ "tx_stn_cpu_0" 4;
+ "tx_stn_cpu_1" 4;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_cpu_4" 4;
+ "tx_stn_cpu_5" 4;
+ "tx_stn_cpu_6" 4;
+ "tx_stn_cpu_7" 4;
+}
+
+bucket "xgs_0_tx_1" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_0_tx_2" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_0_tx_3" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_0_tx_4" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+bucket "xgs_0_tx_5" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_0_tx_6" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_0_tx_7" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_0_tx_8" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_0_tx_9" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_0_tx_10" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+
+bucket "xgs_0_tx_11" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_0_tx_12" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_0_tx_13" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_0_tx_14" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+
+bucket "xgs_1_rfr" {
+ size 32;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_cpu_4" 4;
+ "tx_stn_cpu_5" 4;
+ "tx_stn_cpu_6" 4;
+ "tx_stn_cpu_7" 4;
+ "tx_stn_xgs_1" 4;
+}
+
+bucket "xgs_1_tx_0" {
+ size 32;
+ "tx_stn_cpu_0" 4;
+ "tx_stn_cpu_1" 4;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_cpu_4" 4;
+ "tx_stn_cpu_5" 4;
+ "tx_stn_cpu_6" 4;
+ "tx_stn_cpu_7" 4;
+}
+
+
+bucket "xgs_1_tx_1" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_1_tx_2" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_1_tx_3" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_1_tx_4" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_1_tx_5" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_1_tx_6" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_1_tx_7" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+
+bucket "xgs_1_tx_8" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+
+bucket "xgs_1_tx_9" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+
+bucket "xgs_1_tx_10" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_1_tx_11" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_1_tx_12" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_1_tx_13" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+bucket "xgs_1_tx_14" {
+ size 16;
+ "tx_stn_cpu_0" 2;
+ "tx_stn_cpu_1" 2;
+ "tx_stn_cpu_2" 2;
+ "tx_stn_cpu_3" 2;
+ "tx_stn_cpu_4" 2;
+ "tx_stn_cpu_5" 2;
+ "tx_stn_cpu_6" 2;
+ "tx_stn_cpu_7" 2;
+}
+
+
+
+
+
+
+/*************************************************************/
+// Security Message Station
+
+bucket "sec_pipe_0" {
+ size 128;
+ "tx_stn_cpu_0" 16;
+ "tx_stn_cpu_1" 16;
+ "tx_stn_cpu_2" 16;
+ "tx_stn_cpu_3" 16;
+ "tx_stn_cpu_4" 16;
+ "tx_stn_cpu_5" 16;
+ "tx_stn_cpu_6" 16;
+ "tx_stn_cpu_7" 16;
+}
+
+bucket "sec_rsa" {
+ size 128;
+ "tx_stn_cpu_0" 16;
+ "tx_stn_cpu_1" 16;
+ "tx_stn_cpu_2" 16;
+ "tx_stn_cpu_3" 16;
+ "tx_stn_cpu_4" 16;
+ "tx_stn_cpu_5" 16;
+ "tx_stn_cpu_6" 16;
+ "tx_stn_cpu_7" 16;
+}
+
diff --git a/sys/mips/rmi/msgring.h b/sys/mips/rmi/msgring.h
new file mode 100755
index 0000000..43be638
--- /dev/null
+++ b/sys/mips/rmi/msgring.h
@@ -0,0 +1,529 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#ifndef _RMI_MSGRING_H_
+#define _RMI_MSGRING_H_
+
+#include <mips/rmi/xlrconfig.h>
+
+#define MSGRNG_TX_BUF_REG 0
+#define MSGRNG_RX_BUF_REG 1
+
+#define MSGRNG_MSG_STATUS_REG 2
+#define MSGRNG_MSG_CONFIG_REG 3
+
+#define MSGRNG_MSG_BUCKSIZE_REG 4
+
+#define MSGRNG_CC_0_REG 16
+#define MSGRNG_CC_1_REG 17
+#define MSGRNG_CC_2_REG 18
+#define MSGRNG_CC_3_REG 19
+#define MSGRNG_CC_4_REG 20
+#define MSGRNG_CC_5_REG 21
+#define MSGRNG_CC_6_REG 22
+#define MSGRNG_CC_7_REG 23
+#define MSGRNG_CC_8_REG 24
+#define MSGRNG_CC_9_REG 25
+#define MSGRNG_CC_10_REG 26
+#define MSGRNG_CC_11_REG 27
+#define MSGRNG_CC_12_REG 28
+#define MSGRNG_CC_13_REG 29
+#define MSGRNG_CC_14_REG 30
+#define MSGRNG_CC_15_REG 31
+
+#define msgrng_read_status() read_c2_register32(MSGRNG_MSG_STATUS_REG, 0)
+
+#define msgrng_read_config() read_c2_register32(MSGRNG_MSG_CONFIG_REG, 0)
+#define msgrng_write_config(value) write_c2_register32(MSGRNG_MSG_CONFIG_REG, 0, value)
+
+#define msgrng_read_bucksize(bucket) read_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, bucket)
+#define msgrng_write_bucksize(bucket, value) write_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, bucket, value)
+
+#define msgrng_read_cc(reg, pri) read_c2_register32(reg, pri)
+#define msgrng_write_cc(reg, value, pri) write_c2_register32(reg, pri, value)
+
+#define msgrng_load_rx_msg0() read_c2_register64(MSGRNG_RX_BUF_REG, 0)
+#define msgrng_load_rx_msg1() read_c2_register64(MSGRNG_RX_BUF_REG, 1)
+#define msgrng_load_rx_msg2() read_c2_register64(MSGRNG_RX_BUF_REG, 2)
+#define msgrng_load_rx_msg3() read_c2_register64(MSGRNG_RX_BUF_REG, 3)
+
+#define msgrng_load_tx_msg0(value) write_c2_register64(MSGRNG_TX_BUF_REG, 0, value)
+#define msgrng_load_tx_msg1(value) write_c2_register64(MSGRNG_TX_BUF_REG, 1, value)
+#define msgrng_load_tx_msg2(value) write_c2_register64(MSGRNG_TX_BUF_REG, 2, value)
+#define msgrng_load_tx_msg3(value) write_c2_register64(MSGRNG_TX_BUF_REG, 3, value)
+
+/* Station IDs */
+#define MSGRNG_STNID_CPU0 0x00
+#define MSGRNG_STNID_CPU1 0x08
+#define MSGRNG_STNID_CPU2 0x10
+#define MSGRNG_STNID_CPU3 0x18
+#define MSGRNG_STNID_CPU4 0x20
+#define MSGRNG_STNID_CPU5 0x28
+#define MSGRNG_STNID_CPU6 0x30
+#define MSGRNG_STNID_CPU7 0x38
+#define MSGRNG_STNID_XGS0_TX 64
+#define MSGRNG_STNID_XMAC0_00_TX 64
+#define MSGRNG_STNID_XMAC0_01_TX 65
+#define MSGRNG_STNID_XMAC0_02_TX 66
+#define MSGRNG_STNID_XMAC0_03_TX 67
+#define MSGRNG_STNID_XMAC0_04_TX 68
+#define MSGRNG_STNID_XMAC0_05_TX 69
+#define MSGRNG_STNID_XMAC0_06_TX 70
+#define MSGRNG_STNID_XMAC0_07_TX 71
+#define MSGRNG_STNID_XMAC0_08_TX 72
+#define MSGRNG_STNID_XMAC0_09_TX 73
+#define MSGRNG_STNID_XMAC0_10_TX 74
+#define MSGRNG_STNID_XMAC0_11_TX 75
+#define MSGRNG_STNID_XMAC0_12_TX 76
+#define MSGRNG_STNID_XMAC0_13_TX 77
+#define MSGRNG_STNID_XMAC0_14_TX 78
+#define MSGRNG_STNID_XMAC0_15_TX 79
+
+#define MSGRNG_STNID_XGS1_TX 80
+#define MSGRNG_STNID_XMAC1_00_TX 80
+#define MSGRNG_STNID_XMAC1_01_TX 81
+#define MSGRNG_STNID_XMAC1_02_TX 82
+#define MSGRNG_STNID_XMAC1_03_TX 83
+#define MSGRNG_STNID_XMAC1_04_TX 84
+#define MSGRNG_STNID_XMAC1_05_TX 85
+#define MSGRNG_STNID_XMAC1_06_TX 86
+#define MSGRNG_STNID_XMAC1_07_TX 87
+#define MSGRNG_STNID_XMAC1_08_TX 88
+#define MSGRNG_STNID_XMAC1_09_TX 89
+#define MSGRNG_STNID_XMAC1_10_TX 90
+#define MSGRNG_STNID_XMAC1_11_TX 91
+#define MSGRNG_STNID_XMAC1_12_TX 92
+#define MSGRNG_STNID_XMAC1_13_TX 93
+#define MSGRNG_STNID_XMAC1_14_TX 94
+#define MSGRNG_STNID_XMAC1_15_TX 95
+
+#define MSGRNG_STNID_GMAC 96
+#define MSGRNG_STNID_GMACJFR_0 96
+#define MSGRNG_STNID_GMACRFR_0 97
+#define MSGRNG_STNID_GMACTX0 98
+#define MSGRNG_STNID_GMACTX1 99
+#define MSGRNG_STNID_GMACTX2 100
+#define MSGRNG_STNID_GMACTX3 101
+#define MSGRNG_STNID_GMACJFR_1 102
+#define MSGRNG_STNID_GMACRFR_1 103
+
+#define MSGRNG_STNID_DMA 104
+#define MSGRNG_STNID_DMA_0 104
+#define MSGRNG_STNID_DMA_1 105
+#define MSGRNG_STNID_DMA_2 106
+#define MSGRNG_STNID_DMA_3 107
+
+#define MSGRNG_STNID_XGS0FR 112
+#define MSGRNG_STNID_XMAC0JFR 112
+#define MSGRNG_STNID_XMAC0RFR 113
+
+#define MSGRNG_STNID_XGS1FR 114
+#define MSGRNG_STNID_XMAC1JFR 114
+#define MSGRNG_STNID_XMAC1RFR 115
+#define MSGRNG_STNID_SEC 120
+#define MSGRNG_STNID_SEC0 120
+#define MSGRNG_STNID_SEC1 121
+#define MSGRNG_STNID_SEC2 122
+#define MSGRNG_STNID_SEC3 123
+#define MSGRNG_STNID_PK0 124
+#define MSGRNG_STNID_SEC_RSA 124
+#define MSGRNG_STNID_SEC_RSVD0 125
+#define MSGRNG_STNID_SEC_RSVD1 126
+#define MSGRNG_STNID_SEC_RSVD2 127
+
+#define MSGRNG_STNID_GMAC1 80
+#define MSGRNG_STNID_GMAC1_FR_0 81
+#define MSGRNG_STNID_GMAC1_TX0 82
+#define MSGRNG_STNID_GMAC1_TX1 83
+#define MSGRNG_STNID_GMAC1_TX2 84
+#define MSGRNG_STNID_GMAC1_TX3 85
+#define MSGRNG_STNID_GMAC1_FR_1 87
+#define MSGRNG_STNID_GMAC0 96
+#define MSGRNG_STNID_GMAC0_FR_0 97
+#define MSGRNG_STNID_GMAC0_TX0 98
+#define MSGRNG_STNID_GMAC0_TX1 99
+#define MSGRNG_STNID_GMAC0_TX2 100
+#define MSGRNG_STNID_GMAC0_TX3 101
+#define MSGRNG_STNID_GMAC0_FR_1 103
+#define MSGRNG_STNID_CMP_0 108
+#define MSGRNG_STNID_CMP_1 109
+#define MSGRNG_STNID_CMP_2 110
+#define MSGRNG_STNID_CMP_3 111
+#define MSGRNG_STNID_PCIE_0 116
+#define MSGRNG_STNID_PCIE_1 117
+#define MSGRNG_STNID_PCIE_2 118
+#define MSGRNG_STNID_PCIE_3 119
+#define MSGRNG_STNID_XLS_PK0 121
+
+#define MSGRNG_CODE_MAC 0
+#define MSGRNG_CODE_XGMAC 2
+#define MSGRNG_CODE_SEC 0
+#define MSGRNG_CODE_BOOT_WAKEUP 200
+#define MSGRNG_CODE_SPI4 3
+
+static inline int
+msgrng_xgmac_stid_rfr(int id)
+{
+ return !id ? MSGRNG_STNID_XMAC0RFR : MSGRNG_STNID_XMAC1RFR;
+}
+
+static inline int
+msgrng_xgmac_stid_jfr(int id)
+{
+ return !id ? MSGRNG_STNID_XMAC0JFR : MSGRNG_STNID_XMAC1JFR;
+}
+
+static inline int
+msgrng_xgmac_stid_tx(int id)
+{
+ return !id ? MSGRNG_STNID_XMAC0_00_TX : MSGRNG_STNID_XMAC1_00_TX;
+}
+
+static inline int
+msgrng_gmac_stid_rfr(int id)
+{
+ return (MSGRNG_STNID_GMACRFR_0);
+}
+
+static inline int
+msgrng_gmac_stid_rfr_split_mode(int id)
+{
+ return ((id >> 1) ? MSGRNG_STNID_GMACRFR_1 : MSGRNG_STNID_GMACRFR_0);
+}
+
+static inline int
+msgrng_gmac_stid_jfr(int id)
+{
+ return MSGRNG_STNID_GMACJFR_0;
+}
+
+static inline int
+msgrng_gmac_stid_jfr_split_mode(int id)
+{
+ return ((id >> 1) ? MSGRNG_STNID_GMACJFR_1 : MSGRNG_STNID_GMACJFR_0);
+}
+
+static inline int
+msgrng_gmac_stid_tx(int id)
+{
+ return (MSGRNG_STNID_GMACTX0 + id);
+}
+
+static inline void
+msgrng_send(unsigned int stid)
+{
+ __asm__ volatile (
+ ".set push\n"
+ ".set noreorder\n"
+ "sync\n"
+ // "msgsnd %0\n"
+ "move $8, %0\n"
+ "c2 0x80001\n"
+ ".set pop\n"
+ :: "r" (stid):"$8"
+ );
+}
+
+static inline void
+msgrng_receive(unsigned int pri)
+{
+ __asm__ volatile (
+ ".set push\n"
+ ".set noreorder\n"
+ // "msgld %0\n"
+ "move $8, %0\n"
+ "c2 0x80002\n"
+ ".set pop\n"
+ :: "r" (pri):"$8"
+ );
+}
+static inline void
+msgrng_wait(unsigned int mask)
+{
+ __asm__ volatile (
+ ".set push\n"
+ ".set noreorder\n"
+ // "msgwait %0\n"
+ "move $8, %0\n"
+ "c2 0x80003\n"
+ ".set pop\n"
+ :: "r" (mask):"$8"
+ );
+}
+
+#define msgrng_enable(flags) \
+do { \
+ __asm__ volatile ( \
+ ".set push\n\t" \
+ ".set reorder\n\t" \
+ ".set noat\n\t" \
+ "mfc0 %0, $12\n\t" \
+ "li $8, 0x40000001\n\t" \
+ "or $1, %0, $8\n\t" \
+ "xori $1, 1\n\t" \
+ ".set noreorder\n\t" \
+ "mtc0 $1, $12\n\t" \
+ ".set\tpop\n\t" \
+ : "=r" (flags) \
+ : \
+ : "$8" \
+ ); \
+} while (0)
+
+#define msgrng_disable(flags) __asm__ volatile ( \
+ "mtc0 %0, $12" : : "r" (flags))
+
+#define msgrng_flags_save(flags) msgrng_enable(flags)
+#define msgrng_flags_restore(flags) msgrng_disable(flags)
+
+struct msgrng_msg {
+ __uint64_t msg0;
+ __uint64_t msg1;
+ __uint64_t msg2;
+ __uint64_t msg3;
+};
+
+static inline void
+message_send_block_fast(int size, unsigned int code, unsigned int stid,
+ unsigned long long msg0, unsigned long long msg1,
+ unsigned long long msg2, unsigned long long msg3)
+{
+ __asm__ __volatile__(".set push\n"
+ ".set noreorder\n"
+ ".set mips64\n"
+ "dmtc2 %1, $0, 0\n"
+ "dmtc2 %2, $0, 1\n"
+ "dmtc2 %3, $0, 2\n"
+ "dmtc2 %4, $0, 3\n"
+ "move $8, %0\n"
+ "1: c2 0x80001\n"
+ "mfc2 $8, $2\n"
+ "andi $8, $8, 0x6\n"
+ "bnez $8, 1b\n"
+ "move $8, %0\n"
+ ".set pop\n"
+ :
+ : "r"(((size - 1) << 16) | (code << 8) | stid), "r"(msg0), "r"(msg1), "r"(msg2), "r"(msg3)
+ : "$8"
+ );
+}
+
+#define message_receive_fast(bucket, size, code, stid, msg0, msg1, msg2, msg3) \
+ ( { unsigned int _status=0, _tmp=0; \
+ msgrng_receive(bucket); \
+ while ( (_status=msgrng_read_status()) & 0x08) ; \
+ _tmp = _status & 0x30; \
+ if (__builtin_expect((!_tmp), 1)) { \
+ (size)=((_status & 0xc0)>>6)+1; \
+ (code)=(_status & 0xff00)>>8; \
+ (stid)=(_status & 0x7f0000)>>16; \
+ (msg0)=msgrng_load_rx_msg0(); \
+ (msg1)=msgrng_load_rx_msg1(); \
+ (msg2)=msgrng_load_rx_msg2(); \
+ (msg3)=msgrng_load_rx_msg3(); \
+ _tmp=0; \
+ } \
+ _tmp; \
+ } )
+
+static __inline__ int
+message_send(unsigned int size, unsigned int code,
+ unsigned int stid, struct msgrng_msg *msg)
+{
+ unsigned int dest = 0;
+ unsigned long long status = 0;
+ int i = 0;
+
+ msgrng_load_tx_msg0(msg->msg0);
+ msgrng_load_tx_msg1(msg->msg1);
+ msgrng_load_tx_msg2(msg->msg2);
+ msgrng_load_tx_msg3(msg->msg3);
+
+ dest = ((size - 1) << 16) | (code << 8) | (stid);
+
+ //dbg_msg("Sending msg<%Lx,%Lx,%Lx,%Lx> to dest = %x\n",
+ //msg->msg0, msg->msg1, msg->msg2, msg->msg3, dest);
+
+ msgrng_send(dest);
+
+ for (i = 0; i < 16; i++) {
+ status = msgrng_read_status();
+ //dbg_msg("status = %Lx\n", status);
+
+ if (status & 0x6) {
+ continue;
+ } else
+ break;
+ }
+ if (i == 16) {
+ if (dest == 0x61)
+ //dbg_msg("Processor %x: Unable to send msg to %llx\n", processor_id(), dest);
+ return status & 0x6;
+ }
+ return msgrng_read_status() & 0x06;
+}
+
+static __inline__ int
+message_send_retry(unsigned int size, unsigned int code,
+ unsigned int stid, struct msgrng_msg *msg)
+{
+ int res = 0;
+ int retry = 0;
+
+ for (;;) {
+ res = message_send(size, code, stid, msg);
+ /* retry a pending fail */
+ if (res & 0x02)
+ continue;
+ /* credit fail */
+ if (res & 0x04)
+ retry++;
+ else
+ break;
+ if (retry == 4)
+ return res & 0x06;
+ }
+
+ return 0;
+}
+
+static __inline__ int
+message_receive(int pri, int *size, int *code, int *src_id,
+ struct msgrng_msg *msg)
+{
+ int res = message_receive_fast(pri, *size, *code, *src_id, msg->msg0, msg->msg1, msg->msg2, msg->msg3);
+
+#ifdef MSGRING_DUMP_MESSAGES
+ if (!res) {
+ dbg_msg("Received msg <%llx, %llx, %llx, %llx> <%d,%d,%d>\n",
+ msg->msg0, msg->msg1, msg->msg2, msg->msg3,
+ *size, *code, *src_id);
+ }
+#endif
+
+ return res;
+}
+
+#define MSGRNG_STN_RX_QSIZE 256
+
+struct stn_cc {
+ unsigned short counters[16][8];
+};
+
+struct bucket_size {
+ unsigned short bucket[128];
+};
+
+extern struct bucket_size bucket_sizes;
+
+extern struct stn_cc cc_table_cpu_0;
+extern struct stn_cc cc_table_cpu_1;
+extern struct stn_cc cc_table_cpu_2;
+extern struct stn_cc cc_table_cpu_3;
+extern struct stn_cc cc_table_cpu_4;
+extern struct stn_cc cc_table_cpu_5;
+extern struct stn_cc cc_table_cpu_6;
+extern struct stn_cc cc_table_cpu_7;
+extern struct stn_cc cc_table_xgs_0;
+extern struct stn_cc cc_table_xgs_1;
+extern struct stn_cc cc_table_gmac;
+extern struct stn_cc cc_table_dma;
+extern struct stn_cc cc_table_sec;
+
+extern struct bucket_size xls_bucket_sizes;
+
+extern struct stn_cc xls_cc_table_cpu_0;
+extern struct stn_cc xls_cc_table_cpu_1;
+extern struct stn_cc xls_cc_table_cpu_2;
+extern struct stn_cc xls_cc_table_cpu_3;
+extern struct stn_cc xls_cc_table_gmac0;
+extern struct stn_cc xls_cc_table_gmac1;
+extern struct stn_cc xls_cc_table_cmp;
+extern struct stn_cc xls_cc_table_pcie;
+extern struct stn_cc xls_cc_table_dma;
+extern struct stn_cc xls_cc_table_sec;
+
+
+#define msgrng_access_save(lock, mflags) do { \
+ if (rmi_spin_mutex_safe) mtx_lock_spin(lock); \
+ msgrng_flags_save(mflags); \
+ }while(0)
+
+#define msgrng_access_restore(lock, mflags) do { \
+ msgrng_flags_restore(mflags); \
+ if (rmi_spin_mutex_safe) mtx_unlock_spin(lock); \
+ }while(0)
+
+#define msgrng_access_enable(mflags) do { \
+ critical_enter(); \
+ msgrng_flags_save(mflags); \
+} while(0)
+
+#define msgrng_access_disable(mflags) do { \
+ msgrng_flags_restore(mflags); \
+ critical_exit(); \
+} while(0)
+
+/*
+ * NOTE: this is not stationid/8, ie the station numbers below are just
+ * for internal use
+ */
+enum {
+ TX_STN_CPU_0,
+ TX_STN_CPU_1,
+ TX_STN_CPU_2,
+ TX_STN_CPU_3,
+ TX_STN_CPU_4,
+ TX_STN_CPU_5,
+ TX_STN_CPU_6,
+ TX_STN_CPU_7,
+ TX_STN_GMAC,
+ TX_STN_DMA,
+ TX_STN_XGS_0,
+ TX_STN_XGS_1,
+ TX_STN_SAE,
+ TX_STN_GMAC0,
+ TX_STN_GMAC1,
+ TX_STN_CDE,
+ TX_STN_PCIE,
+ TX_STN_INVALID,
+ MAX_TX_STNS
+};
+
+extern int
+register_msgring_handler(int major,
+ void (*action) (int, int, int, int, struct msgrng_msg *, void *),
+ void *dev_id);
+ extern void xlr_msgring_cpu_init(void);
+
+ extern void xlr_msgring_config(void);
+
+#define cpu_to_msgring_bucket(cpu) ((((cpu) >> 2)<<3)|((cpu) & 0x03))
+
+#endif
diff --git a/sys/mips/rmi/msgring_xls.c b/sys/mips/rmi/msgring_xls.c
new file mode 100644
index 0000000..bd86187
--- /dev/null
+++ b/sys/mips/rmi/msgring_xls.c
@@ -0,0 +1,217 @@
+/**********************************************************
+ * -----------------DO NOT EDIT THIS FILE------------------
+ * This file has been autogenerated by the build process
+ * from "msgring_xls.cfg"
+ **********************************************************/
+
+#include <mips/rmi/msgring.h>
+
+struct bucket_size xls_bucket_sizes = {
+ {32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 32, 32, 32, 32, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 32, 32, 32, 32, 32, 0, 0,
+ 64, 64, 64, 64, 32, 32, 32, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 128, 128, 0, 0, 0, 0, 0, 0,
+ }
+};
+
+struct stn_cc xls_cc_table_cpu_0 = {{
+ {1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 8, 0, 0, 0, 0},
+ {0, 0, 0, 8, 0, 0, 0, 0},
+ {0, 0, 0, 8, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 8, 8, 8, 8, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 8, 8, 8, 8, 0, 0},
+ {16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {32, 32, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc xls_cc_table_cpu_1 = {{
+ {1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 8, 8, 8, 8, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 8, 8, 8, 8, 0, 0},
+ {16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {32, 32, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc xls_cc_table_cpu_2 = {{
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 8, 8, 8, 8, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 8, 8, 8, 8, 0, 0},
+ {16, 16, 16, 16, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {32, 32, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc xls_cc_table_cpu_3 = {{
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 8, 8, 8, 8, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 4, 8, 8, 8, 8, 0, 0},
+ {16, 16, 16, 16, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {32, 32, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc xls_cc_table_gmac0 = {{
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 8, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 8, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc xls_cc_table_gmac1 = {{
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {8, 8, 8, 8, 8, 8, 8, 8},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 8, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 8, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc xls_cc_table_dma = {{
+ {4, 4, 4, 4, 4, 4, 4, 4},
+ {4, 4, 4, 2, 4, 4, 4, 4},
+ {4, 4, 4, 2, 4, 4, 4, 4},
+ {4, 4, 4, 2, 4, 4, 4, 4},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc xls_cc_table_cmp = {{
+ {4, 4, 4, 4, 4, 4, 4, 4},
+ {4, 4, 4, 2, 4, 4, 4, 4},
+ {4, 4, 4, 2, 4, 4, 4, 4},
+ {4, 4, 4, 2, 4, 4, 4, 4},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc xls_cc_table_pcie = {{
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+}};
+
+struct stn_cc xls_cc_table_sec = {{
+ {6, 8, 8, 8, 0, 0, 0, 0},
+ {8, 8, 8, 4, 0, 0, 0, 0},
+ {8, 8, 8, 4, 0, 0, 0, 0},
+ {8, 8, 8, 4, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+}};
diff --git a/sys/mips/rmi/msgring_xls.cfg b/sys/mips/rmi/msgring_xls.cfg
new file mode 100755
index 0000000..35bfb17
--- /dev/null
+++ b/sys/mips/rmi/msgring_xls.cfg
@@ -0,0 +1,563 @@
+/*********************************************************************
+ *
+ * Copyright 2003-2006 Raza Microelectronics, Inc. (RMI). 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 Raza Microelectronics, Inc. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RMI OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************RMI_2**********************************/
+
+
+/*
+ * This file defines the message ring configuration for XLS two core. It tries to allow
+ * many different point-point communications between the message stations on the message ring
+ * and as result is _not_ the best configuration for performance
+ *
+ * The message ring on phoenix family of processors connects the cpus, gmacs, xgmac/spi4,
+ * security engine and the general purpose DMA engines. It provides a high bandwidth,
+ * low latency communication links. On traditional processors, this communication goes through
+ * which inherently does not scale very well with increasing number of cpus.
+ *
+ * Message ring has an in-built flow control mechanism. Every agent/station on the ring has to
+ * have software configured credits to send messages to any agent. Every receiving agent on the
+ * ring has a 256 entry FIFO that can divided into "buckets". All addressing on the ring is
+ * in terms of buckets. There are a total 128 buckets on the ring. The total number of credits
+ * across all sending agents should not exceed the bucket size.
+ *
+ * Below are the receiving agents and the max number of buckets they can have
+ * CPU 0 : 8 buckets
+ * CPU 1 : 8 buckets
+ *
+ * GMAC : 8 buckets
+ *
+ * SEC : 8 buckets
+ *
+ * DMA : 8 buckets
+ *
+ * CMP : Currently disabled.
+ *
+ * The bucket size of a bucket should be aligned to the bucket's starting index in that
+ * receiving station's FIFO. For example, if sizes of bucket0 and bucket1 of a station
+ * are 32 and 32, bucket2's size has to be 64. bucket size 0 is valid.
+ *
+ * The format of the file is pretty straight forward. Each bucket definition has the size
+ * and the list of sending agents to that bucket with the number of credits to send.
+ *
+ * Undefined buckets have a size of 0 and Tx stations have 0 credits to send to that bucket.
+ *
+ * Following are the currently supported bucket names
+ * cpu_0_0
+ * cpu_0_1
+ * cpu_0_2
+ * cpu_0_3
+ * cpu_0_4
+ * cpu_0_5
+ * cpu_0_6
+ * cpu_0_7
+ *
+ * cpu_1_0
+ * cpu_1_1
+ * cpu_1_2
+ * cpu_1_3
+ * cpu_1_4
+ * cpu_1_5
+ * cpu_1_6
+ * cpu_1_7
+ *
+ * enabled only for xls-b0
+ * cpu_2_0
+ * cpu_2_1
+ * cpu_2_2
+ * cpu_2_3
+ * cpu_2_4
+ * cpu_2_5
+ * cpu_2_6
+ * cpu_2_7
+ *
+ * enabled only for xls-b0
+ * cpu_3_0
+ * cpu_3_1
+ * cpu_3_2
+ * cpu_3_3
+ * cpu_3_4
+ * cpu_3_5
+ * cpu_3_6
+ * cpu_3_7
+ *
+ * gmac0_rfr
+ * gmac0_tx_0
+ * gmac0_tx_1
+ * gmac0_tx_2
+ * gmac0_tx_3
+ *
+ * gmac1_rfr
+ * gmac1_tx_0
+ * gmac1_tx_1
+ * gmac1_tx_2
+ * gmac1_tx_3
+ *
+ * sec_pipe_0
+ * sec_rsa
+ *
+ * Following are the currently supported Tx Agent/Station names
+ *
+ * tx_stn_cpu_0
+ * tx_stn_cpu_1
+ *
+ * tx_stn_gmac0
+ * tx_stn_gmac1
+ *
+ * tx_stn_dma
+ *
+ * tx_stn_sec
+ *
+ *
+ */
+
+/*************************************************************/
+// CPU_0 Message Station
+
+bucket "cpu_0_0" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 6;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+ "tx_stn_cpu_0" 1;
+ "tx_stn_cpu_1" 1; /* NEEDED BY RMIOS IPSEC */
+}
+bucket "cpu_0_1" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_0_2" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_0_3" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_0_4" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_0_5" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_0_6" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_0_7" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+
+/*************************************************************/
+// CPU_1 Message Station
+
+bucket "cpu_1_0" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_1_1" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_1_2" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_1_3" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 4;
+ "tx_stn_cpu_0" 8; /* NEEDED BY RMIOS IPSEC */
+ "tx_stn_dma" 2;
+ "tx_stn_cmp" 2;
+}
+bucket "cpu_1_4" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_1_5" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_1_6" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_1_7" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+
+/*************************************************************/
+// CPU_2 Message Station
+
+bucket "cpu_2_0" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_2_1" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_2_2" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_2_3" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 4;
+ "tx_stn_cpu_0" 8; /* NEEDED BY RMIOS IPSEC */
+ "tx_stn_dma" 2;
+ "tx_stn_cmp" 2;
+}
+bucket "cpu_2_4" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_2_5" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_2_6" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_2_7" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+
+
+/*************************************************************/
+// CPU_3 Message Station
+bucket "cpu_3_0" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_3_1" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_3_2" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_3_3" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_sec" 4;
+ "tx_stn_cpu_0" 8; /* NEEDED BY RMIOS IPSEC */
+ "tx_stn_dma" 2;
+ "tx_stn_cmp" 2;
+}
+bucket "cpu_3_4" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_3_5" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_3_6" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+bucket "cpu_3_7" {
+ size 32;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+ "tx_stn_dma" 4;
+ "tx_stn_cmp" 4;
+}
+
+/*************************************************************/
+
+// GMAC Message Station
+
+bucket "gmac0_rfr" {
+ size 32;
+ "tx_stn_cpu_0" 4;
+ "tx_stn_cpu_1" 4;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+}
+
+bucket "gmac0_tx_0" {
+ size 32;
+ "tx_stn_cpu_0" 8;
+ "tx_stn_cpu_1" 8;
+ "tx_stn_cpu_2" 8;
+ "tx_stn_cpu_3" 8;
+}
+
+bucket "gmac0_tx_1" {
+ size 32;
+ "tx_stn_cpu_0" 8;
+ "tx_stn_cpu_1" 8;
+ "tx_stn_cpu_2" 8;
+ "tx_stn_cpu_3" 8;
+}
+
+bucket "gmac0_tx_2" {
+ size 32;
+ "tx_stn_cpu_0" 8;
+ "tx_stn_cpu_1" 8;
+ "tx_stn_cpu_2" 8;
+ "tx_stn_cpu_3" 8;
+}
+
+bucket "gmac0_tx_3" {
+ size 32;
+ "tx_stn_cpu_0" 8;
+ "tx_stn_cpu_1" 8;
+ "tx_stn_cpu_2" 8;
+ "tx_stn_cpu_3" 8;
+}
+
+bucket "gmac1_rfr" {
+ size 32;
+ "tx_stn_cpu_0" 4;
+ "tx_stn_cpu_1" 4;
+ "tx_stn_cpu_2" 4;
+ "tx_stn_cpu_3" 4;
+ "tx_stn_gmac0" 8;
+ "tx_stn_gmac1" 8;
+}
+
+bucket "gmac1_tx_0" {
+ size 32;
+ "tx_stn_cpu_0" 8;
+ "tx_stn_cpu_1" 8;
+ "tx_stn_cpu_2" 8;
+ "tx_stn_cpu_3" 8;
+}
+
+bucket "gmac1_tx_1" {
+ size 32;
+ "tx_stn_cpu_0" 8;
+ "tx_stn_cpu_1" 8;
+ "tx_stn_cpu_2" 8;
+ "tx_stn_cpu_3" 8;
+}
+
+bucket "gmac1_tx_2" {
+ size 32;
+ "tx_stn_cpu_0" 8;
+ "tx_stn_cpu_1" 8;
+ "tx_stn_cpu_2" 8;
+ "tx_stn_cpu_3" 8;
+}
+
+bucket "gmac1_tx_3" {
+ size 32;
+ "tx_stn_cpu_0" 8;
+ "tx_stn_cpu_1" 8;
+ "tx_stn_cpu_2" 8;
+ "tx_stn_cpu_3" 8;
+}
+
+/*************************************************************/
+// Security Message Station
+
+bucket "sec_pipe_0" {
+ size 128;
+ "tx_stn_cpu_0" 32;
+ "tx_stn_cpu_1" 32;
+ "tx_stn_cpu_2" 32;
+ "tx_stn_cpu_3" 32;
+}
+
+bucket "sec_rsa_ecc" {
+ size 128;
+ "tx_stn_cpu_0" 32;
+ "tx_stn_cpu_1" 32;
+ "tx_stn_cpu_2" 32;
+ "tx_stn_cpu_3" 32;
+}
+
+bucket "dma_rsvd_0" {
+ size 64;
+ "tx_stn_cpu_0" 16;
+ "tx_stn_cpu_1" 16;
+ "tx_stn_cpu_2" 16;
+ "tx_stn_cpu_3" 16;
+}
+bucket "dma_rsvd_1" {
+ size 64;
+ "tx_stn_cpu_0" 16;
+ "tx_stn_cpu_1" 16;
+ "tx_stn_cpu_2" 16;
+ "tx_stn_cpu_3" 16;
+}
+
+bucket "dma_rsvd_2" {
+ size 64;
+ "tx_stn_cpu_0" 16;
+ "tx_stn_cpu_1" 16;
+ "tx_stn_cpu_2" 16;
+ "tx_stn_cpu_3" 16;
+}
+
+bucket "dma_rsvd_3" {
+ size 64;
+ "tx_stn_cpu_0" 16;
+ "tx_stn_cpu_1" 16;
+ "tx_stn_cpu_2" 16;
+ "tx_stn_cpu_3" 16;
+}
+
+/*************************************************************/
+// Compression Message Station
+
+bucket "cmp_0" {
+ size 32;
+ "tx_stn_cpu_0" 16;
+ "tx_stn_cpu_1" 16;
+}
+
+bucket "cmp_1" {
+ size 32;
+ "tx_stn_cpu_0" 16;
+ "tx_stn_cpu_1" 16;
+}
+
+bucket "cmp_2" {
+ size 32;
+ "tx_stn_cpu_0" 16;
+ "tx_stn_cpu_1" 16;
+}
+
+bucket "cmp_3" {
+ size 32;
+ "tx_stn_cpu_0" 16;
+ "tx_stn_cpu_1" 16;
+}
+
diff --git a/sys/mips/rmi/on_chip.c b/sys/mips/rmi/on_chip.c
new file mode 100644
index 0000000..c0c73c4
--- /dev/null
+++ b/sys/mips/rmi/on_chip.c
@@ -0,0 +1,330 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/limits.h>
+#include <sys/bus.h>
+
+#include <machine/reg.h>
+#include <machine/cpu.h>
+#include <machine/mips_opcode.h>
+
+#include <machine/param.h>
+#include <machine/intr_machdep.h>
+#include <mips/rmi/interrupt.h>
+#include <mips/rmi/msgring.h>
+#include <mips/rmi/iomap.h>
+#include <mips/rmi/debug.h>
+#include <mips/rmi/pic.h>
+#include <mips/rmi/board.h>
+
+void
+disable_msgring_int(void *arg);
+void
+enable_msgring_int(void *arg);
+
+/* definitions */
+struct tx_stn_handler {
+ void (*action) (int, int, int, int, struct msgrng_msg *, void *);
+ void *dev_id;
+};
+
+/* globals */
+static struct tx_stn_handler tx_stn_handlers[MAX_TX_STNS];
+
+#define MSGRNG_CC_INIT_CPU_DEST(dest, counter) \
+do { \
+ msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][0], 0 ); \
+ msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][1], 1 ); \
+ msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][2], 2 ); \
+ msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][3], 3 ); \
+ msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][4], 4 ); \
+ msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][5], 5 ); \
+ msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][6], 6 ); \
+ msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][7], 7 ); \
+} while(0)
+
+
+/* make this a read/write spinlock */
+static struct mtx msgrng_lock;
+static int msgring_int_enabled;
+struct mtx xlr_pic_lock;
+
+static int msgring_pop_num_buckets;
+static uint32_t msgring_pop_bucket_mask;
+static int msgring_int_type;
+static int msgring_watermark_count;
+static uint32_t msgring_thread_mask;
+
+uint32_t msgrng_msg_cycles = 0;
+
+int xlr_counters[MAXCPU][XLR_MAX_COUNTERS] __aligned(XLR_CACHELINE_SIZE);
+
+void xlr_msgring_handler(struct trapframe *);
+
+void
+xlr_msgring_cpu_init(void)
+{
+ struct stn_cc *cc_config;
+ struct bucket_size *bucket_sizes;
+ int id;
+ unsigned long flags;
+
+ /* if not thread 0 */
+ if (xlr_thr_id() != 0)
+ return;
+ id = xlr_cpu_id();
+
+ bucket_sizes = xlr_board_info.bucket_sizes;
+ cc_config = xlr_board_info.credit_configs[id];
+
+ msgrng_flags_save(flags);
+
+ /*
+ * Message Stations are shared among all threads in a cpu core
+ * Assume, thread 0 on all cores are always active when more than 1
+ * thread is active in a core
+ */
+ msgrng_write_bucksize(0, bucket_sizes->bucket[id * 8 + 0]);
+ msgrng_write_bucksize(1, bucket_sizes->bucket[id * 8 + 1]);
+ msgrng_write_bucksize(2, bucket_sizes->bucket[id * 8 + 2]);
+ msgrng_write_bucksize(3, bucket_sizes->bucket[id * 8 + 3]);
+ msgrng_write_bucksize(4, bucket_sizes->bucket[id * 8 + 4]);
+ msgrng_write_bucksize(5, bucket_sizes->bucket[id * 8 + 5]);
+ msgrng_write_bucksize(6, bucket_sizes->bucket[id * 8 + 6]);
+ msgrng_write_bucksize(7, bucket_sizes->bucket[id * 8 + 7]);
+
+ MSGRNG_CC_INIT_CPU_DEST(0, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(1, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(2, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(3, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(4, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(5, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(6, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(7, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(8, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(9, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(10, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(11, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(12, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(13, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(14, cc_config->counters);
+ MSGRNG_CC_INIT_CPU_DEST(15, cc_config->counters);
+
+ msgrng_flags_restore(flags);
+}
+
+void
+xlr_msgring_config(void)
+{
+ msgring_int_type = 0x02;
+ msgring_pop_num_buckets = 8;
+ msgring_pop_bucket_mask = 0xff;
+
+ msgring_watermark_count = 1;
+ msgring_thread_mask = 0x01;
+/* printf("[%s]: int_type = 0x%x, pop_num_buckets=%d, pop_bucket_mask=%x" */
+/* "watermark_count=%d, thread_mask=%x\n", __FUNCTION__, */
+/* msgring_int_type, msgring_pop_num_buckets, msgring_pop_bucket_mask, */
+/* msgring_watermark_count, msgring_thread_mask); */
+}
+
+void
+xlr_msgring_handler(struct trapframe *tf)
+{
+ unsigned long mflags;
+ int bucket = 0;
+ int size = 0, code = 0, rx_stid = 0, tx_stid = 0;
+ struct msgrng_msg msg;
+ unsigned int bucket_empty_bm = 0;
+ unsigned int status = 0;
+
+ xlr_inc_counter(MSGRNG_INT);
+ /* TODO: not necessary to disable preemption */
+ msgrng_flags_save(mflags);
+
+ /* First Drain all the high priority messages */
+ for (;;) {
+ bucket_empty_bm = (msgrng_read_status() >> 24) & msgring_pop_bucket_mask;
+
+ /* all buckets empty, break */
+ if (bucket_empty_bm == msgring_pop_bucket_mask)
+ break;
+
+ for (bucket = 0; bucket < msgring_pop_num_buckets; bucket++) {
+ uint32_t cycles = 0;
+
+ if ((bucket_empty_bm & (1 << bucket)) /* empty */ )
+ continue;
+
+ status = message_receive(bucket, &size, &code, &rx_stid, &msg);
+ if (status)
+ continue;
+
+ xlr_inc_counter(MSGRNG_MSG);
+ msgrng_msg_cycles = mips_rd_count();
+ cycles = msgrng_msg_cycles;
+
+ tx_stid = xlr_board_info.msgmap[rx_stid];
+
+ if (!tx_stn_handlers[tx_stid].action) {
+ printf("[%s]: No Handler for message from stn_id=%d, bucket=%d, "
+ "size=%d, msg0=%llx, dropping message\n",
+ __FUNCTION__, tx_stid, bucket, size, msg.msg0);
+ } else {
+ //printf("[%s]: rx_stid = %d\n", __FUNCTION__, rx_stid);
+ msgrng_flags_restore(mflags);
+ (*tx_stn_handlers[tx_stid].action) (bucket, size, code, rx_stid,
+ &msg, tx_stn_handlers[tx_stid].dev_id);
+ msgrng_flags_save(mflags);
+ }
+ xlr_set_counter(MSGRNG_MSG_CYCLES, (read_c0_count() - cycles));
+ }
+ }
+
+ xlr_set_counter(MSGRNG_EXIT_STATUS, msgrng_read_status());
+
+ msgrng_flags_restore(mflags);
+
+ //dbg_msg("OUT irq=%d\n", irq);
+
+ /* Call the msg callback */
+}
+
+void
+enable_msgring_int(void *arg)
+{
+ unsigned long mflags = 0;
+
+ msgrng_access_save(&msgrng_lock, mflags);
+ /* enable the message ring interrupts */
+ msgrng_write_config((msgring_watermark_count << 24) | (IRQ_MSGRING << 16)
+ | (msgring_thread_mask << 8) | msgring_int_type);
+ msgrng_access_restore(&msgrng_lock, mflags);
+}
+
+void
+disable_msgring_int(void *arg)
+{
+ unsigned long mflags = 0;
+ uint32_t config;
+
+ msgrng_access_save(&msgrng_lock, mflags);
+ config = msgrng_read_config();
+ config &= ~0x3;
+ msgrng_write_config(config);
+ msgrng_access_restore(&msgrng_lock, mflags);
+}
+
+extern void platform_prep_smp_launch(void);
+extern void msgring_process_fast_intr(void *arg);
+
+int
+register_msgring_handler(int major,
+ void (*action) (int, int, int, int, struct msgrng_msg *, void *),
+ void *dev_id)
+{
+ void *cookie; /* FIXME - use? */
+
+ if (major >= MAX_TX_STNS)
+ return 1;
+
+ //dbg_msg("major=%d, action=%p, dev_id=%p\n", major, action, dev_id);
+
+ if (rmi_spin_mutex_safe)
+ mtx_lock_spin(&msgrng_lock);
+ tx_stn_handlers[major].action = action;
+ tx_stn_handlers[major].dev_id = dev_id;
+ if (rmi_spin_mutex_safe)
+ mtx_unlock_spin(&msgrng_lock);
+
+ if (xlr_test_and_set(&msgring_int_enabled)) {
+ platform_prep_smp_launch();
+
+ cpu_establish_hardintr("msgring", (driver_filter_t *) NULL,
+ (driver_intr_t *) msgring_process_fast_intr,
+ NULL, IRQ_MSGRING, INTR_TYPE_NET | INTR_FAST, &cookie);
+
+ /* configure the msgring interrupt on cpu 0 */
+ enable_msgring_int(NULL);
+ }
+ return 0;
+}
+
+static void
+pic_init(void)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+ int i = 0;
+ int level;
+
+ dbg_msg("Initializing PIC...\n");
+ for (i = 0; i < PIC_NUM_IRTS; i++) {
+
+ level = PIC_IRQ_IS_EDGE_TRIGGERED(i);
+
+ /* Bind all PIC irqs to cpu 0 */
+ xlr_write_reg(mmio, PIC_IRT_0_BASE + i, 0x01);
+
+ /*
+ * Use local scheduling and high polarity for all IRTs
+ * Invalidate all IRTs, by default
+ */
+ xlr_write_reg(mmio, PIC_IRT_1_BASE + i, (level << 30) | (1 << 6) | (PIC_IRQ_BASE + i));
+ }
+ dbg_msg("PIC init now done\n");
+}
+
+void
+on_chip_init(void)
+{
+ int i = 0, j = 0;
+
+ /* Set xlr_io_base to the run time value */
+ mtx_init(&msgrng_lock, "msgring", NULL, MTX_SPIN | MTX_RECURSE);
+ mtx_init(&xlr_pic_lock, "pic", NULL, MTX_SPIN);
+
+ xlr_board_info_setup();
+
+ msgring_int_enabled = 0;
+
+ xlr_msgring_config();
+ pic_init();
+
+ xlr_msgring_cpu_init();
+
+ for (i = 0; i < MAXCPU; i++)
+ for (j = 0; j < XLR_MAX_COUNTERS; j++)
+ atomic_set_int(&xlr_counters[i][j], 0);
+}
diff --git a/sys/mips/rmi/pcibus.c b/sys/mips/rmi/pcibus.c
new file mode 100644
index 0000000..ac664d3
--- /dev/null
+++ b/sys/mips/rmi/pcibus.c
@@ -0,0 +1,357 @@
+/*-
+ * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/alpha/pci/pcibus.c,v 1.36 2005/01/05 20:05:52 imp Exp $");
+
+#include "opt_isa.h"
+
+#define __RMAN_RESOURCE_VISIBLE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/module.h>
+#include <sys/proc.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/pmap.h>
+#include <sys/interrupt.h>
+#include <sys/sysctl.h>
+#include <mips/rmi/iomap.h>
+#include <mips/rmi/pic.h>
+#include <mips/rmi/shared_structs.h>
+#include <mips/rmi/board.h>
+#include <sys/rman.h>
+
+#include <dev/pci/pcivar.h>
+#include <machine/resource.h>
+#include <machine/md_var.h>
+#include <machine/intr_machdep.h>
+#include <mips/rmi/pcibus.h>
+/*
+static void bridge_pcix_ack(void *);
+static void bridge_pcie_ack(void *);
+static void pic_pcix_ack(void *);
+static void pic_pcie_ack(void *);
+*/
+
+extern vm_map_t kernel_map;
+vm_offset_t kmem_alloc_nofault(vm_map_t map, vm_size_t size);
+
+
+int
+mips_pci_route_interrupt(device_t bus, device_t dev, int pin)
+{
+ /*
+ * Validate requested pin number.
+ */
+ if ((pin < 1) || (pin > 4))
+ return (255);
+
+ if (xlr_board_info.is_xls) {
+ switch (pin) {
+ case 1:
+ return PIC_PCIE_LINK0_IRQ;
+ case 2:
+ return PIC_PCIE_LINK1_IRQ;
+ case 3:
+ return PIC_PCIE_LINK2_IRQ;
+ case 4:
+ return PIC_PCIE_LINK3_IRQ;
+ }
+ } else {
+ if (pin == 1) {
+ return (16);
+ }
+ }
+
+ return (255);
+}
+
+static struct rman irq_rman, port_rman, mem_rman;
+
+/*
+static void bridge_pcix_ack(void *arg)
+{
+ xlr_read_reg(xlr_io_mmio(XLR_IO_PCIX_OFFSET), 0x140 >> 2);
+ }
+*/
+/*
+static void bridge_pcie_ack(void *arg)
+{
+ int irq = (int)arg;
+ uint32_t reg;
+ xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET);
+
+ switch (irq) {
+ case PIC_PCIE_LINK0_IRQ : reg = PCIE_LINK0_MSI_STATUS; break;
+ case PIC_PCIE_LINK1_IRQ : reg = PCIE_LINK1_MSI_STATUS; break;
+ case PIC_PCIE_LINK2_IRQ : reg = PCIE_LINK2_MSI_STATUS; break;
+ case PIC_PCIE_LINK3_IRQ : reg = PCIE_LINK3_MSI_STATUS; break;
+ default:
+ return;
+ }
+
+ xlr_write_reg(pcie_mmio_le, reg>>2, 0xffffffff);
+}
+*/
+/*
+static void pic_pcix_ack(void *none)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_INT_ACK, (1 << PIC_IRT_PCIX_INDEX));
+ mtx_unlock_spin(&xlr_pic_lock);
+}
+*/
+/*
+static void pic_pcie_ack(void *arg)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+ int irq = (int) arg;
+
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
+ mtx_unlock_spin(&xlr_pic_lock);
+}
+
+*/
+
+int
+mips_platform_pci_setup_intr(device_t dev, device_t child,
+ struct resource *irq, int flags,
+ driver_filter_t * filt,
+ driver_intr_t * intr, void *arg,
+ void **cookiep)
+{
+ int level;
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+ int error = 0;
+ int xlrirq;
+
+ error = rman_activate_resource(irq);
+ if (error)
+ return error;
+ if (rman_get_start(irq) != rman_get_end(irq)) {
+ device_printf(dev, "Interrupt allocation %lu != %lu\n",
+ rman_get_start(irq), rman_get_end(irq));
+ return EINVAL;
+ }
+ xlrirq = rman_get_start(irq);
+ if (strcmp(device_get_name(dev), "pcib") != 0)
+ return 0;
+
+ if (xlr_board_info.is_xls == 0) {
+
+ if (rmi_spin_mutex_safe) mtx_lock_spin(&xlr_pic_lock);
+ level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_PCIX_INDEX);
+ xlr_write_reg(mmio, PIC_IRT_0_PCIX, 0x01);
+ xlr_write_reg(mmio, PIC_IRT_1_PCIX, ((1 << 31) | (level << 30) |
+ (1 << 6) | (PIC_PCIX_IRQ)));
+ if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock);
+ cpu_establish_hardintr(device_get_name(child), filt,
+ (driver_intr_t *) intr, (void *)arg, PIC_PCIX_IRQ, flags, cookiep);
+
+ } else {
+ if (rmi_spin_mutex_safe) mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_IRT_0_BASE + xlrirq - PIC_IRQ_BASE, 0x01);
+ xlr_write_reg(mmio, PIC_IRT_1_BASE + xlrirq - PIC_IRQ_BASE,
+ ((1 << 31) | (1 << 30) | (1 << 6) | xlrirq));
+ if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock);
+
+ if (flags & INTR_FAST)
+ cpu_establish_hardintr(device_get_name(child), filt,
+ (driver_intr_t *) intr, (void *)arg, xlrirq, flags, cookiep);
+ else
+ cpu_establish_hardintr(device_get_name(child), filt,
+ (driver_intr_t *) intr, (void *)arg, xlrirq, flags, cookiep);
+
+
+ }
+ return bus_generic_setup_intr(dev, child, irq, flags, filt, intr,
+ arg, cookiep);
+}
+
+
+int
+mips_platform_pci_teardown_intr(device_t dev, device_t child,
+ struct resource *irq, void *cookie);
+int
+mips_platform_pci_teardown_intr(device_t dev, device_t child,
+ struct resource *irq, void *cookie)
+{
+ if (strcmp(device_get_name(child), "pci") == 0) {
+ /* if needed reprogram the pic to clear pcix related entry */
+ }
+ return bus_generic_teardown_intr(dev, child, irq, cookie);
+}
+
+void
+pci_init_resources(void)
+{
+ irq_rman.rm_start = 0;
+ irq_rman.rm_end = 255;
+ irq_rman.rm_type = RMAN_ARRAY;
+ irq_rman.rm_descr = "PCI Mapped Interrupts";
+ if (rman_init(&irq_rman)
+ || rman_manage_region(&irq_rman, 0, 255))
+ panic("pci_init_resources irq_rman");
+
+ port_rman.rm_start = 0;
+ port_rman.rm_end = ~0u;
+ port_rman.rm_type = RMAN_ARRAY;
+ port_rman.rm_descr = "I/O ports";
+ if (rman_init(&port_rman)
+ || rman_manage_region(&port_rman, 0x10000000, 0x1fffffff))
+ panic("pci_init_resources port_rman");
+
+ mem_rman.rm_start = 0;
+ mem_rman.rm_end = ~0u;
+ mem_rman.rm_type = RMAN_ARRAY;
+ mem_rman.rm_descr = "I/O memory";
+ if (rman_init(&mem_rman)
+ || rman_manage_region(&mem_rman, 0xd0000000, 0xdfffffff))
+ panic("pci_init_resources mem_rman");
+}
+
+/* hack from bus.h in mips/include/bus.h */
+#ifndef MIPS_BUS_SPACE_PCI
+#define MIPS_BUS_SPACE_PCI 10
+#endif
+
+struct resource *
+xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct rman *rm;
+ struct resource *rv;
+ vm_offset_t va;
+ int needactivate = flags & RF_ACTIVE;
+
+#if 0
+ device_printf(bus, "xlr_pci_alloc_resource : child %s, type %d, start %lx end %lx, count %lx, flags %x\n",
+ device_get_nameunit(child), type, start, end, count, flags);
+#endif
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ rm = &irq_rman;
+ break;
+
+ case SYS_RES_IOPORT:
+ rm = &port_rman;
+ break;
+
+ case SYS_RES_MEMORY:
+ rm = &mem_rman;
+ break;
+
+ default:
+ return 0;
+ }
+
+ rv = rman_reserve_resource(rm, start, end, count, flags, child);
+ if (rv == 0)
+ return 0;
+
+ rman_set_bustag(rv, (bus_space_tag_t) MIPS_BUS_SPACE_PCI);
+ rman_set_rid(rv, *rid);
+
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ /*
+ * if ((start + count) > (2 << 28)) { va_start =
+ * kmem_alloc_nofault(kernel_map, count); }
+ */
+ /*
+ * This called for pmap_map_uncached, but the pmap_map calls
+ * pmap_kenter which does a is_cacheable_mem() check and
+ * thus sets the PTE_UNCACHED bit. Hopefully this will work
+ * for this guy... RRS
+ */
+ /* va = pmap_map(&va_start, start, start + count, 0); */
+ va = (vm_offset_t)pmap_mapdev(start, start + count);
+ rman_set_bushandle(rv, va);
+ /* bushandle is same as virtual addr */
+ rman_set_virtual(rv, (void *)va);
+ rman_set_bustag(rv, (bus_space_tag_t) MIPS_BUS_SPACE_PCI);
+ }
+ if (needactivate) {
+ if (bus_activate_resource(child, type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
+ }
+ }
+ return rv;
+}
+
+
+int
+pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_deactivate_resource(r));
+}
+
+/* now in pci.c
+int
+pci_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_activate_resource(r));
+}
+
+int
+pci_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_release_resource(r));
+}
+*/
+
+struct rman *
+pci_get_rman(device_t dev, int type)
+{
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return &port_rman;
+
+ case SYS_RES_MEMORY:
+ return &mem_rman;
+
+ case SYS_RES_IRQ:
+ return &irq_rman;
+ }
+
+ return 0;
+}
diff --git a/sys/mips/rmi/pcibus.h b/sys/mips/rmi/pcibus.h
new file mode 100644
index 0000000..deea39c
--- /dev/null
+++ b/sys/mips/rmi/pcibus.h
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/alpha/pci/pcibus.h,v 1.5 2002/02/28 18:18:41 gallatin Exp $
+ */
+#define DEFAULT_PCI_CONFIG_BASE 0x18000000
+
+#define MSI_MIPS_ADDR_BASE 0xfee00000
+
+
+#define PCIE_LINK0_MSI_STATUS 0x90
+#define PCIE_LINK1_MSI_STATUS 0x94
+#define PCIE_LINK2_MSI_STATUS 0x190
+#define PCIE_LINK3_MSI_STATUS 0x194
+
+void pci_init_resources(void);
+struct resource *
+xlr_pci_alloc_resource(device_t bus, device_t child,
+ int type, int *rid,
+ u_long start, u_long end, u_long count,
+ u_int flags);
+int
+pci_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r);
+int
+pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r);
+int
+pci_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r);
+struct rman *pci_get_rman(device_t dev, int type);
+
+int
+mips_platform_pci_setup_intr(device_t dev, device_t child,
+ struct resource *irq, int flags,
+ driver_filter_t * filt,
+ driver_intr_t * intr, void *arg,
+ void **cookiep);
+int
+ mips_pci_route_interrupt(device_t bus, device_t dev, int pin);
diff --git a/sys/mips/rmi/perfmon.h b/sys/mips/rmi/perfmon.h
new file mode 100644
index 0000000..555b181
--- /dev/null
+++ b/sys/mips/rmi/perfmon.h
@@ -0,0 +1,183 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+
+#ifndef PERFMON_H
+#define PERFMON_H
+
+#include <mips/rmi/perfmon_xlrconfig.h>
+
+/*
+ * category events reported by the perfmon library
+ */
+enum event_category_t {
+ PERF_CP0_COUNTER = 1, PERF_CP2_CREDITS, PERF_L2_COUNTER,
+ PERF_SBC_COUNTER, PERF_SBC_CREDITS, PERF_GMAC0_COUNTER, PERF_GMAC1_COUNTER,
+ PERF_GMAC2_COUNTER, PERF_GMAC_STAT_COM, PERF_GMAC_STAT_TX,
+PERF_GMAC_STAT_RX, PERF_DRAM_COUNTER, PERF_PARAMETER_CONF = 127};
+
+
+enum perf_param_t {
+ PERF_CPU_SAMPLING_INTERVAL, PERF_SYS_SAMPLING_INTERVAL, PERF_CC_SAMPLE_RATE, PERF_CP0_FLAGS
+};
+
+#define CPO_EVENTS_TEMPLATE 0x06 /* enable kernel and user events */
+
+#define PERFMON_ACTIVE_MAGIC 0xc001
+#define PERFMON_ENABLED_MAGIC 0xb007
+#define PERFMON_INITIAL_GENERATION 0x0101
+
+#define PERFMON_SERVER_PORT 7007
+
+enum system_bridge_credits_t {
+ PCIX_CREDITS, HT_CREDITS, GIO_CREDITS, OTHER_CREDITS
+};
+
+struct perf_config_data {
+ uint16_t magic; /* monitor start when this is initialized */
+ uint16_t generation; /* incremented when the config changes */
+ uint16_t flags;
+ uint16_t cc_sample_rate;/* rate at which credit counters are sampled
+ * relative to sampling_rate */
+ uint32_t sampling_rate; /* rate at which events are sampled */
+ uint32_t cc_register_mask; /* credit counters registers to be
+ * sampled */
+ uint64_t events[NTHREADS]; /* events bitmap for each thread */
+};
+
+struct perf_sample {
+ uint32_t counter;
+ uint32_t timestamp;
+ uint32_t sample_tag;
+ uint32_t duration;
+};
+
+struct sample_q {
+ int32_t head, tail;
+ struct perf_sample samples[PERF_SAMPLE_BUFSZ];
+ uint32_t overflows;
+};
+
+struct perf_area {
+ struct perf_config_data perf_config;
+ struct sample_q sample_fifo;
+};
+
+/*
+ * We have a shared location to keep a global tick counter for all the
+ * CPUS - TODO is this optimal? effect on cache?
+ */
+extern uint32_t *xlr_perfmon_timer_loc;
+
+#define PERFMON_TIMESTAMP_LOC (xlr_perfmon_timer_loc)
+
+static __inline__ uint32_t
+perfmon_timestamp_get(void)
+{
+ return *PERFMON_TIMESTAMP_LOC;
+}
+
+static __inline__ void
+perfmon_timestamp_set(uint32_t val)
+{
+ *PERFMON_TIMESTAMP_LOC = val;
+}
+
+static __inline__ void
+perfmon_timestamp_incr(int val)
+{
+ (*PERFMON_TIMESTAMP_LOC) += val;
+}
+
+static __inline__ void
+send_sample_gts(uint32_t tag, uint32_t value, uint32_t td)
+{
+ xlr_send_sample(tag, value, perfmon_timestamp_get(), td);
+}
+
+/*
+ * Simple FIFO, one producer - one consumer - circlar queue - no locking
+ */
+
+static __inline__ void
+init_fifo(struct sample_q *q)
+{
+ q->head = q->tail = 0;
+}
+
+static __inline__ void
+put_sample(struct sample_q *q, uint32_t sample_tag, uint32_t counter,
+ uint32_t duration)
+{
+ uint32_t timestamp = perfmon_timestamp_get();
+ int new_tail = (q->tail + 1) % PERF_SAMPLE_BUFSZ;
+
+ if (q->head == new_tail) {
+ q->overflows++;
+ return;
+ }
+ q->samples[new_tail].sample_tag = sample_tag;
+ q->samples[new_tail].counter = counter;
+ q->samples[new_tail].timestamp = timestamp;
+ q->samples[new_tail].duration = duration;
+
+ q->tail = new_tail;
+}
+
+static __inline__ int
+get_sample(struct sample_q *q, uint32_t * sample_tag, uint32_t * counter,
+ uint32_t * timestamp, uint32_t * duration)
+{
+ int head = q->head;
+
+ if (head == q->tail)
+ return 0;
+ *sample_tag = q->samples[head].sample_tag;
+ *counter = q->samples[head].counter;
+ *timestamp = q->samples[head].timestamp;
+ *duration = q->samples[head].duration;
+
+ q->head = (head + 1) % PERF_SAMPLE_BUFSZ;
+ return 1;
+}
+
+static __inline__ void
+clear_queue(struct sample_q *q)
+{
+ q->head = q->tail;
+}
+void xlr_perfmon_init_cpu(void *);
+void xlr_perfmon_sampler(void *);
+void log_active_core(int core);
+int get_start_generation(void);
+
+void xlr_perfmon_clockhandler(void);
+extern int xlr_perfmon_started;
+
+#endif /* PERFMON_H */
diff --git a/sys/mips/rmi/perfmon_kern.c b/sys/mips/rmi/perfmon_kern.c
new file mode 100644
index 0000000..363bbb2
--- /dev/null
+++ b/sys/mips/rmi/perfmon_kern.c
@@ -0,0 +1,163 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/smp.h>
+#include <sys/sysctl.h>
+#include <machine/smp.h>
+#include <mips/rmi/perfmon.h>
+#include <mips/rmi/pic.h>
+#include <sys/mutex.h>
+#include <mips/rmi/clock.h>
+
+
+int xlr_perfmon_started = 0;
+struct perf_area *xlr_shared_config_area = NULL;
+uint32_t *xlr_perfmon_timer_loc;
+uint32_t *xlr_cpu_sampling_interval;
+uint32_t xlr_perfmon_kernel_version = 1; /* Future use */
+uint32_t xlr_perfmon_ticks;
+extern int mips_cpu_online_mask;
+extern uint32_t cpu_ltop_map[MAXCPU];
+
+#ifdef SMP
+static __inline__ void
+pic_send_perfmon_ipi(int cpu)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+ int tid, pid;
+ uint32_t ipi;
+
+ tid = cpu & 0x3;
+ pid = (cpu >> 2) & 0x7;
+ ipi = (pid << 20) | (tid << 16) | IPI_PERFMON;
+
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_IPI, ipi);
+ mtx_unlock_spin(&xlr_pic_lock);
+}
+
+#endif
+
+
+void
+xlr_perfmon_clockhandler(void)
+{
+#ifdef SMP
+ int cpu;
+ int i;
+
+#endif
+
+ if (xlr_perfmon_ticks++ >= (*xlr_cpu_sampling_interval) / (XLR_PIC_HZ / (hz * 1024))) {
+
+ /* update timer */
+ *xlr_perfmon_timer_loc += *xlr_cpu_sampling_interval;
+ xlr_perfmon_ticks = 0;
+ xlr_perfmon_sampler(NULL);
+#ifdef SMP
+ for (i = 0; i < NCPUS; i = i + NTHREADS) { /* oly thread 0 */
+ cpu = cpu_ltop_map[i];
+ if ((mips_cpu_online_mask & (1 << i)) &&
+ xlr_shared_config_area[cpu / NTHREADS].perf_config.magic ==
+ PERFMON_ACTIVE_MAGIC)
+ pic_send_perfmon_ipi(cpu);
+ }
+
+#endif
+
+ }
+}
+
+static void
+xlr_perfmon_start(void)
+{
+ size_t size;
+
+ size = (NCORES * sizeof(*xlr_shared_config_area)) +
+ sizeof(*xlr_perfmon_timer_loc) +
+ sizeof(*xlr_cpu_sampling_interval);
+
+ xlr_shared_config_area = malloc(size, M_TEMP, M_WAITOK);
+ if (!xlr_shared_config_area) {
+ /* ERROR */
+ return;
+ }
+ xlr_perfmon_timer_loc = (uint32_t *) (xlr_shared_config_area + NCORES);
+ xlr_cpu_sampling_interval = (uint32_t *) (xlr_perfmon_timer_loc + 1);
+
+ *xlr_cpu_sampling_interval = DEFAULT_CPU_SAMPLING_INTERVAL;
+ *xlr_perfmon_timer_loc = 0;
+ xlr_perfmon_ticks = 0;
+
+ xlr_perfmon_init_cpu(NULL);
+#ifdef SMP
+ smp_call_function(xlr_perfmon_init_cpu, NULL,
+ PCPU_GET(other_cpus) & 0x11111111);
+#endif
+ xlr_perfmon_started = 1;
+
+}
+
+static void
+xlr_perfmon_stop(void)
+{
+ xlr_perfmon_started = 0;
+ free(xlr_shared_config_area, M_TEMP);
+ xlr_shared_config_area = NULL;
+}
+
+static int
+sysctl_xlr_perfmon_start_stop(SYSCTL_HANDLER_ARGS)
+{
+ int error, val = xlr_perfmon_started;
+
+ error = sysctl_handle_int(oidp, &val, 0, req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+
+ if (!xlr_perfmon_started && val != 0)
+ xlr_perfmon_start();
+ else if (xlr_perfmon_started && val == 0)
+ xlr_perfmon_stop();
+
+ return (0);
+}
+
+
+SYSCTL_NODE(_debug, OID_AUTO, xlrperf, CTLFLAG_RW, NULL, "XLR PERF Nodes");
+SYSCTL_PROC(_debug_xlrperf, OID_AUTO, start, CTLTYPE_INT | CTLFLAG_RW,
+ &xlr_perfmon_started, 0, sysctl_xlr_perfmon_start_stop, "I", "set/unset to start/stop "
+ "performance monitoring");
diff --git a/sys/mips/rmi/perfmon_percpu.c b/sys/mips/rmi/perfmon_percpu.c
new file mode 100644
index 0000000..fc0f062
--- /dev/null
+++ b/sys/mips/rmi/perfmon_percpu.c
@@ -0,0 +1,342 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/smp.h>
+#include <sys/pcpu.h>
+#include <mips/rmi/xlrconfig.h>
+#include <mips/rmi/perfmon_xlrconfig.h>
+#include <mips/rmi/perfmon.h>
+#include <mips/rmi/perfmon_utils.h>
+#include <mips/rmi/pic.h>
+#include <mips/rmi/msgring.h>
+
+#define CC_SAMPLE (PERF_CP2_CREDITS <<24)
+
+#define CC_REG0 16
+#define CC_REG1 17
+#define CC_REG2 18
+#define CC_REG3 19
+#define CC_REG4 20
+#define CC_REG5 21
+#define CC_REG6 22
+#define CC_REG7 23
+#define CC_REG8 24
+#define CC_REG9 25
+#define CC_REG10 26
+#define CC_REG11 27
+#define CC_REG12 28
+#define CC_REG13 29
+#define CC_REG14 30
+#define CC_REG15 31
+
+extern uint32_t cpu_ltop_map[MAXCPU];
+extern struct perf_area *xlr_shared_config_area;
+
+static __inline__ uint32_t
+make_cpu_tag(uint32_t val)
+{
+ return PERF_CP0_COUNTER << 24 | (val & 0xffff);
+}
+
+static __inline__ uint32_t
+make_cp0_perf_control(uint32_t flags, uint32_t thread, uint32_t event)
+{
+ return (flags & 0x1f) | (thread & 0x03) << 11 | (event & 0x3f) << 5 | 0x01;
+}
+
+static __inline__ uint32_t
+cp0_perf_control_get_thread(uint32_t control_word)
+{
+ return (control_word & 0x1800) >> 11;
+}
+
+static __inline__ uint32_t
+cp0_perf_control_get_event(uint32_t control_word)
+{
+ return (control_word & 0x7e0) >> 5;
+}
+
+static __inline__ uint32_t
+read_pic_6_timer_count(void)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+
+ /* PIC counts down, convert it to count up */
+ return 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0);
+}
+
+
+static uint32_t
+get_num_events(const uint64_t * events)
+{
+ int total = 0;
+ int thread;
+
+ for (thread = 0; thread < NTHREADS; thread++) {
+ if (events[thread] == 0)
+ continue;
+ total += get_set_bit_count64(events[thread]);
+ }
+ return total;
+}
+
+static uint32_t
+get_first_control_word(uint32_t flags, const uint64_t * events)
+{
+ int thread, event;
+
+ for (thread = 0; thread < NTHREADS; thread++) {
+ if (events[thread] != 0)
+ break;
+ }
+ if (thread == NTHREADS)
+ return -1;
+
+ event = find_first_set_bit64(events[thread]);
+ return make_cp0_perf_control(flags, thread, event);
+}
+
+static uint32_t
+get_next_control_word(uint32_t current_control_word, const uint64_t * events)
+{
+ int thread = cp0_perf_control_get_thread(current_control_word);
+ int event = cp0_perf_control_get_event(current_control_word);
+ int i;
+
+ event = find_next_set_bit64(events[thread], event);
+ for (i = 0; event == -1 && i < NTHREADS; i++) {
+ thread = (thread + 1) % NTHREADS;
+ if (events[thread] == 0)
+ continue;
+ event = find_first_set_bit64(events[thread]);
+ }
+
+ ASSERT(event != -1);
+ return make_cp0_perf_control(current_control_word, thread, event);
+}
+
+/* Global state per core */
+#define MY_CORE_NUM (cpu_ltop_map[PCPU_GET(cpuid)]/NTHREADS)
+#define my_perf_area (&(xlr_shared_config_area[MY_CORE_NUM]))
+
+static int num_events_array[NCORES];
+static uint32_t saved_timestamp_array[NCORES];
+static struct perf_config_data saved_config_array[NCORES];
+static int cc_sample_array[NCORES];
+
+#define num_events (num_events_array[MY_CORE_NUM])
+#define saved_timestamp (saved_timestamp_array[MY_CORE_NUM])
+#define saved_config (saved_config_array[MY_CORE_NUM])
+#define cc_sample (cc_sample_array[MY_CORE_NUM])
+
+static void
+do_sample_cc_registers(struct sample_q *q, uint32_t mask)
+{
+ unsigned long flags;
+
+ DPRINT("Sample CC registers %x", mask);
+ msgrng_flags_save(flags);
+ if (mask & 0x00000001)
+ put_sample(q, CC_SAMPLE + 0, read_cc_registers_0123(CC_REG0), 0);
+ if (mask & 0x00000002)
+ put_sample(q, CC_SAMPLE + 1, read_cc_registers_4567(CC_REG0), 0);
+ if (mask & 0x00000004)
+ put_sample(q, CC_SAMPLE + 2, read_cc_registers_0123(CC_REG1), 0);
+ if (mask & 0x00000008)
+ put_sample(q, CC_SAMPLE + 3, read_cc_registers_4567(CC_REG1), 0);
+ if (mask & 0x00000010)
+ put_sample(q, CC_SAMPLE + 4, read_cc_registers_0123(CC_REG2), 0);
+ if (mask & 0x00000020)
+ put_sample(q, CC_SAMPLE + 5, read_cc_registers_4567(CC_REG2), 0);
+ if (mask & 0x00000040)
+ put_sample(q, CC_SAMPLE + 6, read_cc_registers_0123(CC_REG3), 0);
+ if (mask & 0x00000080)
+ put_sample(q, CC_SAMPLE + 7, read_cc_registers_4567(CC_REG3), 0);
+ if (mask & 0x00000100)
+ put_sample(q, CC_SAMPLE + 8, read_cc_registers_0123(CC_REG4), 0);
+ if (mask & 0x00000200)
+ put_sample(q, CC_SAMPLE + 9, read_cc_registers_4567(CC_REG4), 0);
+ if (mask & 0x00000400)
+ put_sample(q, CC_SAMPLE + 10, read_cc_registers_0123(CC_REG5), 0);
+ if (mask & 0x00000800)
+ put_sample(q, CC_SAMPLE + 11, read_cc_registers_4567(CC_REG5), 0);
+ if (mask & 0x00001000)
+ put_sample(q, CC_SAMPLE + 12, read_cc_registers_0123(CC_REG6), 0);
+ if (mask & 0x00002000)
+ put_sample(q, CC_SAMPLE + 13, read_cc_registers_4567(CC_REG6), 0);
+ if (mask & 0x00004000)
+ put_sample(q, CC_SAMPLE + 14, read_cc_registers_0123(CC_REG7), 0);
+ if (mask & 0x00008000)
+ put_sample(q, CC_SAMPLE + 15, read_cc_registers_4567(CC_REG7), 0);
+ if (mask & 0x00010000)
+ put_sample(q, CC_SAMPLE + 16, read_cc_registers_0123(CC_REG8), 0);
+ if (mask & 0x00020000)
+ put_sample(q, CC_SAMPLE + 17, read_cc_registers_4567(CC_REG8), 0);
+ if (mask & 0x00040000)
+ put_sample(q, CC_SAMPLE + 18, read_cc_registers_0123(CC_REG9), 0);
+ if (mask & 0x00080000)
+ put_sample(q, CC_SAMPLE + 19, read_cc_registers_4567(CC_REG9), 0);
+ if (mask & 0x00100000)
+ put_sample(q, CC_SAMPLE + 20, read_cc_registers_0123(CC_REG10), 0);
+ if (mask & 0x00200000)
+ put_sample(q, CC_SAMPLE + 21, read_cc_registers_4567(CC_REG10), 0);
+ if (mask & 0x00400000)
+ put_sample(q, CC_SAMPLE + 22, read_cc_registers_0123(CC_REG11), 0);
+ if (mask & 0x00800000)
+ put_sample(q, CC_SAMPLE + 23, read_cc_registers_4567(CC_REG11), 0);
+ if (mask & 0x01000000)
+ put_sample(q, CC_SAMPLE + 24, read_cc_registers_0123(CC_REG12), 0);
+ if (mask & 0x02000000)
+ put_sample(q, CC_SAMPLE + 24, read_cc_registers_4567(CC_REG12), 0);
+ if (mask & 0x04000000)
+ put_sample(q, CC_SAMPLE + 26, read_cc_registers_0123(CC_REG13), 0);
+ if (mask & 0x08000000)
+ put_sample(q, CC_SAMPLE + 27, read_cc_registers_4567(CC_REG13), 0);
+ if (mask & 0x10000000)
+ put_sample(q, CC_SAMPLE + 28, read_cc_registers_0123(CC_REG14), 0);
+ if (mask & 0x20000000)
+ put_sample(q, CC_SAMPLE + 29, read_cc_registers_4567(CC_REG14), 0);
+ if (mask & 0x40000000)
+ put_sample(q, CC_SAMPLE + 30, read_cc_registers_0123(CC_REG15), 0);
+ if (mask & 0x80000000)
+ put_sample(q, CC_SAMPLE + 31, read_cc_registers_4567(CC_REG15), 0);
+ msgrng_flags_restore(flags);
+}
+
+static void
+reconfigure(void)
+{
+ uint32_t cntr_cntrl;
+
+ saved_config = my_perf_area->perf_config;
+ num_events = get_num_events(saved_config.events);
+ cc_sample = saved_config.cc_sample_rate;
+
+ DPRINT("%d - reconfigure num_events = %d, events = %llx,%llx,%llx,%llx\n",
+ processor_id(), num_events, saved_config.events[0],
+ saved_config.events[1], saved_config.events[2], saved_config.events[3]);
+
+ if (num_events == 0)
+ return;
+
+ cntr_cntrl = get_first_control_word(saved_config.flags, saved_config.events);
+ write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0, cntr_cntrl);
+ write_c0_register(CP0_PERF_COUNTER, PERFCNTR0, 0); /* reset count */
+ if (num_events > 1) {
+ cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events);
+ write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1, cntr_cntrl);
+ write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */
+ }
+ saved_timestamp = read_pic_6_timer_count();
+}
+
+int xlr_perfmon_no_event_count = 0;
+int xlr_perfmon_sample_count;
+
+/* timer callback routine */
+void
+xlr_perfmon_sampler(void *dummy)
+{
+ uint32_t current_ts;
+ uint32_t cntr_cntrl = 0;
+
+ /* xlr_ack_interrupt(XLR_PERFMON_IPI_VECTOR); */
+
+ if (my_perf_area->perf_config.magic != PERFMON_ACTIVE_MAGIC)
+ return;
+ /*
+ * If there has been a change in configuation, update the
+ * configuration
+ */
+ if (saved_config.generation != my_perf_area->perf_config.generation) {
+ reconfigure();
+ return;
+ }
+ /* credit counter samples if reqd */
+ if (saved_config.cc_register_mask && --cc_sample == 0) {
+ cc_sample = saved_config.cc_sample_rate;
+ do_sample_cc_registers(&my_perf_area->sample_fifo,
+ my_perf_area->perf_config.cc_register_mask);
+ }
+ if (num_events == 0) {
+ xlr_perfmon_no_event_count++;
+ return;
+ }
+ /* put samples in the queue */
+ current_ts = read_pic_6_timer_count();
+ cntr_cntrl = read_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0);
+ put_sample(&my_perf_area->sample_fifo, make_cpu_tag(cntr_cntrl),
+ read_c0_register(CP0_PERF_COUNTER, PERFCNTR0), current_ts - saved_timestamp);
+ xlr_perfmon_sample_count++;
+ write_c0_register(CP0_PERF_COUNTER, PERFCNTR0, 0); /* reset count */
+
+ if (num_events > 1) {
+ cntr_cntrl = read_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1);
+ put_sample(&my_perf_area->sample_fifo, make_cpu_tag(cntr_cntrl),
+ read_c0_register(CP0_PERF_COUNTER, PERFCNTR1), current_ts - saved_timestamp);
+ xlr_perfmon_sample_count++;
+ write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */
+
+ if (num_events > 2) {
+ /* multiplex events */
+ cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events);
+ write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0, cntr_cntrl);
+
+ cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events);
+ write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1, cntr_cntrl);
+ }
+ }
+ saved_timestamp = read_pic_6_timer_count();
+}
+
+/*
+ * Initializes time to gather CPU performance counters and credit counters
+ */
+void
+xlr_perfmon_init_cpu(void *dummy)
+{
+ int processor = cpu_ltop_map[PCPU_GET(cpuid)];
+
+ /* run on just one thread per core */
+ if (processor % 4)
+ return;
+
+ DPRINT("%d : configure with %p", processor, my_perf_area);
+ memset(my_perf_area, 0, sizeof(*my_perf_area));
+ init_fifo(&my_perf_area->sample_fifo);
+ my_perf_area->perf_config.magic = PERFMON_ENABLED_MAGIC;
+ my_perf_area->perf_config.generation = PERFMON_INITIAL_GENERATION;
+ DPRINT("%d : Initialize", processor);
+
+ return;
+}
diff --git a/sys/mips/rmi/perfmon_utils.h b/sys/mips/rmi/perfmon_utils.h
new file mode 100644
index 0000000..bafcb54
--- /dev/null
+++ b/sys/mips/rmi/perfmon_utils.h
@@ -0,0 +1,126 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <machine/stdarg.h> /* variable args */
+
+/* TODO optimize of mips, even i & (i-1) is better */
+
+static int __inline__
+get_set_bit_count64(uint64_t value)
+{
+ int i, result = 0;
+
+ for (i = 0; i < sizeof(value) * 8; i++)
+ if (value & (1ULL << i))
+ result++;
+
+ return result;
+}
+
+static int __inline__
+find_first_set_bit64(uint64_t value)
+{
+ int i;
+
+ for (i = 0; i < sizeof(value) * 8; i++)
+ if (value & (1ULL << i))
+ return i;
+
+ return -1;
+}
+
+static int __inline__
+find_next_set_bit64(uint64_t value, int pos)
+{
+ int i;
+
+ for (i = pos + 1; i < sizeof(value) * 8; i++)
+ if (value & (1ULL << i))
+ return i;
+
+ return -1;
+}
+
+/** --- **/
+
+static int __inline__
+get_set_bit_count(uint32_t value)
+{
+ int i, result = 0;
+
+ for (i = 0; i < sizeof(value) * 8; i++)
+ if (value & (1U << i))
+ result++;
+
+ return result;
+}
+
+static int __inline__
+find_first_set_bit(uint32_t value)
+{
+ int i;
+
+ for (i = 0; i < sizeof(value) * 8; i++)
+ if (value & (1U << i))
+ return i;
+
+ return -1;
+}
+
+static int __inline__
+find_next_set_bit(uint32_t value, int pos)
+{
+ int i;
+
+ for (i = pos + 1; i < sizeof(value) * 8; i++)
+ if (value & (1U << i))
+ return i;
+
+ return -1;
+}
+
+#ifdef DEBUG
+void abort();
+
+#define DPUTC(c) (putchar(c) && fflush(stdout))
+#define DPRINT(fmt, ...) printf(fmt "\n", __VA_ARGS__)
+#define ASSERT(x) ((x) || ({ printf("%s failed at (%s:%d)", #x, __FILE__, __LINE__) ; abort(); 0; }) )
+#else
+#define DPUTC(c)
+#define DPRINT(fmt, ...)
+#define ASSERT(x)
+#endif
+
+void xlr_send_sample(uint32_t tag, uint32_t value, uint32_t ts, uint32_t td);
+
+#endif
diff --git a/sys/mips/rmi/perfmon_xlrconfig.h b/sys/mips/rmi/perfmon_xlrconfig.h
new file mode 100644
index 0000000..e3966ae
--- /dev/null
+++ b/sys/mips/rmi/perfmon_xlrconfig.h
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+
+#ifdef XLR_PERFMON
+
+#ifndef XLRCONFIG_PERFMON_H
+#define XLRCONFIG_PERFMON_H
+
+#include <mips/rmi/perfmon_utils.h> /* for DPRINT */
+
+#define NCPUS 32
+#define NCORES 8
+#define NTHREADS 4
+#define PERF_SAMPLE_BUFSZ 32
+/*select timeout is 512*1024 microsecs */
+#define DEFAULT_SYS_SAMPLING_INTERVAL (512*1024)
+/* default timer value programmed to PIC is 10*1024*1024 */
+#define DEFAULT_CPU_SAMPLING_INTERVAL (10*1024)
+#define DEFAULT_CC_SAMPLE_RATE 16
+#define DEFAULT_CP0_FLAGS 0x0A
+#define NUM_L2_BANKS 8
+#define NUM_DRAM_BANKS 4
+
+/* CP0 register for timestamp */
+#define CP0_COUNT 9
+#define CP0_EIRR_REG 9
+#define CP0_EIRR_SEL 6
+#define CP0_EIMR_REG 9
+#define CP0_EIMR_SEL 7
+
+/* CP0 register for perf counters */
+#define CP0_PERF_COUNTER 25
+/* selector values */
+#define PERFCNTRCTL0 0
+#define PERFCNTR0 1
+#define PERFCNTRCTL1 2
+#define PERFCNTR1 3
+
+#define XLR_IO_PIC_OFFSET 0x08000
+#define PIC_SYS_TIMER_0_BASE 0x120
+#define PIC_SYS_TIMER_NUM_6 6
+
+/* CP2 registers for reading credit counters */
+#define CC_REG0 16
+
+#define read_c0_register(reg, sel) \
+({ unsigned int __rv; \
+ __asm__ __volatile__( \
+ ".set\tpush\n\t" \
+ ".set mips32\n\t" \
+ "mfc0\t%0,$%1,%2\n\t" \
+ ".set\tpop" \
+ : "=r" (__rv) : "i" (reg), "i" (sel) ); \
+ __rv;})
+
+#define write_c0_register(reg, sel, value) \
+ __asm__ __volatile__( \
+ ".set\tpush\n\t" \
+ ".set mips32\n\t" \
+ "mtc0\t%0,$%1,%2\n\t" \
+ ".set\tpop" \
+ : : "r" (value), "i" (reg), "i" (sel) );
+
+#define read_c2_register(reg, sel) \
+({ unsigned int __rv; \
+ __asm__ __volatile__( \
+ ".set\tpush\n\t" \
+ ".set mips32\n\t" \
+ "mfc0\t%0,$%1,%2\n\t" \
+ ".set\tpop" \
+ : "=r" (__rv) : "i"(reg), "i" (sel) ); \
+ __rv;})
+
+/*
+ * We have 128 registers in C2 credit counters, reading them one at
+ * a time using bitmap will take a lot of code, so we have two functions
+ * to read registers sel0-3 and sel 4-7 into one 32 bit word.
+ */
+
+#define read_cc_registers_0123(reg) \
+({ \
+ unsigned int __rv; \
+ \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set mips32\n\t" \
+ ".set noreorder\n\t" \
+ "mfc2 %0, $%1, 0\n\t" \
+ "mfc2 $8, $%1, 1\n\t" \
+ "sll %0, %0, 8\n\t" \
+ "or %0, %0, $8\n\t" \
+ "mfc2 $8, $%1, 2\n\t" \
+ "sll %0, %0, 8\n\t" \
+ "or %0, %0, $8\n\t" \
+ "mfc2 $8, $%1, 3\n\t" \
+ "sll %0, %0, 8\n\t" \
+ "or %0, %0, $8\n\t" \
+ ".set pop" \
+ : "=r" (__rv) : "i"(reg) : "$8"); \
+ \
+ __rv; \
+})
+
+#define read_cc_registers_4567(reg) \
+({ \
+ unsigned int __rv; \
+ \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set mips32\n\t" \
+ ".set noreorder\n\t" \
+ "mfc2 %0, $%1, 4\n\t" \
+ "mfc2 $8, $%1, 5\n\t" \
+ "sll %0, %0, 8\n\t" \
+ "or %0, %0, $8\n\t" \
+ "mfc2 $8, $%1, 6\n\t" \
+ "sll %0, %0, 8\n\t" \
+ "or %0, %0, $8\n\t" \
+ "mfc2 $8, $%1, 7\n\t" \
+ "sll %0, %0, 8\n\t" \
+ "or %0, %0, $8\n\t" \
+ ".set pop" \
+ : "=r" (__rv) :"i"(reg) : "$8"); \
+ \
+ __rv; \
+})
+
+#endif
+#endif
diff --git a/sys/mips/rmi/pic.h b/sys/mips/rmi/pic.h
new file mode 100644
index 0000000..1a17724
--- /dev/null
+++ b/sys/mips/rmi/pic.h
@@ -0,0 +1,279 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#ifndef _RMI_PIC_H_
+#define _RMI_PIC_H_
+
+extern int rmi_spin_mutex_safe;
+
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <mips/rmi/iomap.h>
+
+#define PIC_IRT_WD_INDEX 0
+#define PIC_IRT_TIMER_0_INDEX 1
+#define PIC_IRT_TIMER_1_INDEX 2
+#define PIC_IRT_TIMER_2_INDEX 3
+#define PIC_IRT_TIMER_3_INDEX 4
+#define PIC_IRT_TIMER_4_INDEX 5
+#define PIC_IRT_TIMER_5_INDEX 6
+#define PIC_IRT_TIMER_6_INDEX 7
+#define PIC_IRT_TIMER_7_INDEX 8
+#define PIC_IRT_CLOCK_INDEX PIC_IRT_TIMER_7_INDEX
+#define PIC_IRT_UART_0_INDEX 9
+#define PIC_IRT_UART_1_INDEX 10
+#define PIC_IRT_I2C_0_INDEX 11
+#define PIC_IRT_I2C_1_INDEX 12
+#define PIC_IRT_PCMCIA_INDEX 13
+#define PIC_IRT_GPIO_INDEX 14
+#define PIC_IRT_HYPER_INDEX 15
+#define PIC_IRT_PCIX_INDEX 16
+#define PIC_IRT_GMAC0_INDEX 17
+#define PIC_IRT_GMAC1_INDEX 18
+#define PIC_IRT_GMAC2_INDEX 19
+#define PIC_IRT_GMAC3_INDEX 20
+#define PIC_IRT_XGS0_INDEX 21
+#define PIC_IRT_XGS1_INDEX 22
+#define PIC_IRT_HYPER_FATAL_INDEX 23
+#define PIC_IRT_PCIX_FATAL_INDEX 24
+#define PIC_IRT_BRIDGE_AERR_INDEX 25
+#define PIC_IRT_BRIDGE_BERR_INDEX 26
+#define PIC_IRT_BRIDGE_TB_INDEX 27
+#define PIC_IRT_BRIDGE_AERR_NMI_INDEX 28
+
+/* numbering for XLS */
+#define PIC_IRT_BRIDGE_ERR_INDEX 25
+#define PIC_IRT_PCIE_LINK0_INDEX 26
+#define PIC_IRT_PCIE_LINK1_INDEX 27
+#define PIC_IRT_PCIE_LINK2_INDEX 23
+#define PIC_IRT_PCIE_LINK3_INDEX 24
+#define PIC_IRT_PCIE_INT_INDEX 28
+#define PIC_IRT_PCIE_FATAL_INDEX 29
+#define PIC_IRT_GPIO_B_INDEX 30
+#define PIC_IRT_USB_INDEX 31
+
+#define PIC_NUM_IRTS 32
+
+#define PIC_SYS_TIMER_MAXVAL_0_BASE 0x100
+#define PIC_SYS_TIMER_MAXVAL_1_BASE 0x110
+
+#define PIC_SYS_TIMER_0_BASE 0x120
+#define PIC_SYS_TIMER_1_BASE 0x130
+
+#define PIC_CLOCK_TIMER 7
+
+#define PIC_CTRL 0x00
+#define PIC_IPI 0x04
+#define PIC_INT_ACK 0x06
+
+#define WD_MAX_VAL_0 0x08
+#define WD_MAX_VAL_1 0x09
+#define WD_MASK_0 0x0a
+#define WD_MASK_1 0x0b
+#define WD_HEARBEAT_0 0x0c
+#define WD_HEARBEAT_1 0x0d
+
+#define PIC_IRT_0_BASE 0x40
+#define PIC_IRT_1_BASE 0x80
+
+#define PIC_IRT_0_WD (PIC_IRT_0_BASE + PIC_IRT_WD_INDEX)
+#define PIC_IRT_1_WD (PIC_IRT_1_BASE + PIC_IRT_WD_INDEX)
+#define PIC_IRT_0_TIMER_0 (PIC_IRT_0_BASE + PIC_IRT_TIMER_0_INDEX)
+#define PIC_IRT_1_TIMER_0 (PIC_IRT_1_BASE + PIC_IRT_TIMER_0_INDEX)
+#define PIC_IRT_0_TIMER_1 (PIC_IRT_0_BASE + PIC_IRT_TIMER_1_INDEX)
+#define PIC_IRT_1_TIMER_1 (PIC_IRT_1_BASE + PIC_IRT_TIMER_1_INDEX)
+#define PIC_IRT_0_TIMER_2 (PIC_IRT_0_BASE + PIC_IRT_TIMER_2_INDEX)
+#define PIC_IRT_1_TIMER_2 (PIC_IRT_1_BASE + PIC_IRT_TIMER_2_INDEX)
+#define PIC_IRT_0_TIMER_3 (PIC_IRT_0_BASE + PIC_IRT_TIMER_3_INDEX)
+#define PIC_IRT_1_TIMER_3 (PIC_IRT_1_BASE + PIC_IRT_TIMER_3_INDEX)
+#define PIC_IRT_0_TIMER_4 (PIC_IRT_0_BASE + PIC_IRT_TIMER_4_INDEX)
+#define PIC_IRT_1_TIMER_4 (PIC_IRT_1_BASE + PIC_IRT_TIMER_4_INDEX)
+#define PIC_IRT_0_TIMER_5 (PIC_IRT_0_BASE + PIC_IRT_TIMER_5_INDEX)
+#define PIC_IRT_1_TIMER_5 (PIC_IRT_1_BASE + PIC_IRT_TIMER_5_INDEX)
+#define PIC_IRT_0_TIMER_6 (PIC_IRT_0_BASE + PIC_IRT_TIMER_6_INDEX)
+#define PIC_IRT_1_TIMER_6 (PIC_IRT_1_BASE + PIC_IRT_TIMER_6_INDEX)
+#define PIC_IRT_0_TIMER_7 (PIC_IRT_0_BASE + PIC_IRT_TIMER_7_INDEX)
+#define PIC_IRT_1_TIMER_7 (PIC_IRT_1_BASE + PIC_IRT_TIMER_7_INDEX)
+#define PIC_IRT_0_CLOCK (PIC_IRT_0_TIMER_7)
+#define PIC_IRT_1_CLOCK (PIC_IRT_1_TIMER_7)
+#define PIC_IRT_0_UART_0 (PIC_IRT_0_BASE + PIC_IRT_UART_0_INDEX)
+#define PIC_IRT_1_UART_0 (PIC_IRT_1_BASE + PIC_IRT_UART_0_INDEX)
+#define PIC_IRT_0_UART_1 (PIC_IRT_0_BASE + PIC_IRT_UART_1_INDEX)
+#define PIC_IRT_1_UART_1 (PIC_IRT_1_BASE + PIC_IRT_UART_1_INDEX)
+#define PIC_IRT_0_I2C_0 (PIC_IRT_0_BASE + PIC_IRT_I2C_0_INDEX)
+#define PIC_IRT_1_I2C_0 (PIC_IRT_1_BASE + PIC_IRT_I2C_0_INDEX)
+#define PIC_IRT_0_I2C_1 (PIC_IRT_0_BASE + PIC_IRT_I2C_1_INDEX)
+#define PIC_IRT_1_I2C_1 (PIC_IRT_1_BASE + PIC_IRT_I2C_1_INDEX)
+#define PIC_IRT_0_HYPER (PIC_IRT_0_BASE + PIC_IRT_HYPER_INDEX)
+#define PIC_IRT_1_HYPER (PIC_IRT_1_BASE + PIC_IRT_HYPER_INDEX)
+#define PIC_IRT_0_PCIX (PIC_IRT_0_BASE + PIC_IRT_PCIX_INDEX)
+#define PIC_IRT_1_PCIX (PIC_IRT_1_BASE + PIC_IRT_PCIX_INDEX)
+
+#define PIC_TIMER_0_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 0)
+#define PIC_TIMER_0_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 0)
+#define PIC_TIMER_0_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 0)
+#define PIC_TIMER_0_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 0)
+#define PIC_TIMER_6_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 6)
+#define PIC_TIMER_6_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 6)
+#define PIC_TIMER_6_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 6)
+#define PIC_TIMER_6_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 6)
+#define PIC_TIMER_7_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 7)
+#define PIC_TIMER_7_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 7)
+#define PIC_TIMER_7_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 7)
+#define PIC_TIMER_7_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 7)
+
+#define PIC_IRQ_BASE 8
+#define PIC_IRT_FIRST_IRQ PIC_IRQ_BASE
+#define PIC_WD_IRQ (PIC_IRQ_BASE + PIC_IRT_WD_INDEX)
+#define PIC_TIMER_0_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_0_INDEX)
+#define PIC_TIMER_1_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_1_INDEX)
+#define PIC_TIMER_2_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_2_INDEX)
+#define PIC_TIMER_3_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_3_INDEX)
+#define PIC_TIMER_4_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_4_INDEX)
+#define PIC_TIMER_5_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_5_INDEX)
+#define PIC_TIMER_6_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_6_INDEX)
+#define PIC_TIMER_7_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_7_INDEX)
+#define PIC_CLOCK_IRQ (PIC_TIMER_7_IRQ)
+#define PIC_UART_0_IRQ (PIC_IRQ_BASE + PIC_IRT_UART_0_INDEX)
+#define PIC_UART_1_IRQ (PIC_IRQ_BASE + PIC_IRT_UART_1_INDEX)
+#define PIC_I2C_0_IRQ (PIC_IRQ_BASE + PIC_IRT_I2C_0_INDEX)
+#define PIC_I2C_1_IRQ (PIC_IRQ_BASE + PIC_IRT_I2C_1_INDEX)
+#define PIC_PCMCIA_IRQ (PIC_IRQ_BASE + PIC_IRT_PCMCIA_INDEX)
+#define PIC_GPIO_IRQ (PIC_IRQ_BASE + PIC_IRT_GPIO_INDEX)
+#define PIC_HYPER_IRQ (PIC_IRQ_BASE + PIC_IRT_HYPER_INDEX)
+#define PIC_PCIX_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIX_INDEX)
+#define PIC_GMAC_0_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC0_INDEX)
+#define PIC_GMAC_1_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC1_INDEX)
+#define PIC_GMAC_2_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC2_INDEX)
+#define PIC_GMAC_3_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC3_INDEX)
+#define PIC_XGS_0_IRQ (PIC_IRQ_BASE + PIC_IRT_XGS0_INDEX)
+#define PIC_XGS_1_IRQ (PIC_IRQ_BASE + PIC_IRT_XGS1_INDEX)
+#define PIC_HYPER_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_HYPER_FATAL_INDEX)
+#define PIC_PCIX_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIX_FATAL_INDEX)
+#define PIC_BRIDGE_AERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_AERR_INDEX)
+#define PIC_BRIDGE_BERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_BERR_INDEX)
+#define PIC_BRIDGE_TB_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_TB_INDEX)
+#define PIC_BRIDGE_AERR_NMI_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_AERR_NMI_INDEX)
+
+#define PIC_BRIDGE_ERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_ERR_INDEX)
+#define PIC_PCIE_LINK0_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK0_INDEX)
+#define PIC_PCIE_LINK1_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK1_INDEX)
+#define PIC_PCIE_LINK2_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK2_INDEX)
+#define PIC_PCIE_LINK3_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK3_INDEX)
+#define PIC_PCIE_INT_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_INT__INDEX)
+#define PIC_PCIE_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_FATAL_INDEX)
+#define PIC_GPIO_B_IRQ (PIC_IRQ_BASE + PIC_IRT_GPIO_B_INDEX)
+#define PIC_USB_IRQ (PIC_IRQ_BASE + PIC_IRT_USB_INDEX)
+
+#define PIC_IRT_LAST_IRQ PIC_USB_IRQ
+
+#define PIC_IRQ_IS_EDGE_TRIGGERED(irq) ( ((irq)>=PIC_TIMER_0_IRQ) && ((irq)<=PIC_TIMER_7_IRQ) )
+
+#define PIC_IRQ_IS_IRT(irq) ( ((irq)>=PIC_IRT_FIRST_IRQ) && ((irq)<=PIC_IRT_LAST_IRQ) )
+
+
+extern struct mtx xlr_pic_lock;
+
+
+static __inline__ __uint32_t
+pic_read_control(void)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+ __uint32_t reg;
+
+ if (rmi_spin_mutex_safe)
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_read_reg(mmio, PIC_CTRL);
+ if (rmi_spin_mutex_safe)
+ mtx_unlock_spin(&xlr_pic_lock);
+ return reg;
+}
+
+static __inline__ void
+pic_write_control(__uint32_t control)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+
+ if (rmi_spin_mutex_safe)
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_CTRL, control);
+ if (rmi_spin_mutex_safe)
+ mtx_unlock_spin(&xlr_pic_lock);
+}
+static __inline__ void
+pic_update_control(__uint32_t control)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+
+ if (rmi_spin_mutex_safe)
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_CTRL, (control | xlr_read_reg(mmio, PIC_CTRL)));
+ if (rmi_spin_mutex_safe)
+ mtx_unlock_spin(&xlr_pic_lock);
+}
+
+static __inline__ void
+pic_ack(int irq)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+
+ /* ack the pic, if needed */
+ if (!PIC_IRQ_IS_IRT(irq))
+ return;
+
+ if (PIC_IRQ_IS_EDGE_TRIGGERED(irq)) {
+ if (rmi_spin_mutex_safe)
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
+ if (rmi_spin_mutex_safe)
+ mtx_unlock_spin(&xlr_pic_lock);
+ return;
+ }
+ return;
+}
+
+static inline void
+pic_delayed_ack(int irq)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+
+ if (!PIC_IRQ_IS_IRT(irq))
+ return;
+
+ if (!PIC_IRQ_IS_EDGE_TRIGGERED(irq)) {
+ if (rmi_spin_mutex_safe)
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
+ if (rmi_spin_mutex_safe)
+ mtx_unlock_spin(&xlr_pic_lock);
+ return;
+ }
+}
+
+#endif /* _RMI_PIC_H_ */
diff --git a/sys/mips/rmi/rmi_mips_exts.h b/sys/mips/rmi/rmi_mips_exts.h
new file mode 100644
index 0000000..824381a
--- /dev/null
+++ b/sys/mips/rmi/rmi_mips_exts.h
@@ -0,0 +1,144 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#ifndef __MIPS_EXTS_H__
+#define __MIPS_EXTS_H__
+
+#define enable_KX(flags) __asm__ __volatile__ ( \
+ ".set push\n" \
+ ".set noat\n" \
+ ".set noreorder\n" \
+ "mfc0 %0, $12\n\t" \
+ "ori $1, %0, 0x81\n\t" \
+ "xori $1, 1\n\t" \
+ "mtc0 $1, $12\n" \
+ ".set pop\n" \
+ : "=r"(flags) )
+
+#define disable_KX(flags) __asm__ __volatile__ ( \
+ ".set push\n" \
+ "mtc0 %0, $12\n" \
+ ".set pop\n" \
+ : : "r"(flags) )
+
+#define CPU_BLOCKID_IFU 0
+#define CPU_BLOCKID_ICU 1
+#define CPU_BLOCKID_IEU 2
+#define CPU_BLOCKID_LSU 3
+#define CPU_BLOCKID_MMU 4
+#define CPU_BLOCKID_PRF 5
+
+#define LSU_CERRLOG_REGID 9
+
+static __inline__ unsigned int read_32bit_phnx_ctrl_reg(int block, int reg)
+{
+ unsigned int __res;
+
+ __asm__ __volatile__(
+ ".set\tpush\n\t"
+ ".set\tnoreorder\n\t"
+ "move $9, %1\n"
+ /* "mfcr\t$8, $9\n\t" */
+ ".word 0x71280018\n"
+ "move %0, $8\n"
+ ".set\tpop"
+ : "=r" (__res) : "r"((block<<8)|reg)
+ : "$8", "$9"
+ );
+ return __res;
+}
+
+static __inline__ void write_32bit_phnx_ctrl_reg(int block, int reg, unsigned int value)
+{
+ __asm__ __volatile__(
+ ".set\tpush\n\t"
+ ".set\tnoreorder\n\t"
+ "move $8, %0\n"
+ "move $9, %1\n"
+ /* "mtcr\t$8, $9\n\t" */
+ ".word 0x71280019\n"
+ ".set\tpop"
+ :
+ : "r" (value), "r"((block<<8)|reg)
+ : "$8", "$9"
+ );
+}
+
+static __inline__ unsigned long long read_64bit_phnx_ctrl_reg(int block, int reg)
+{
+ unsigned int high, low;
+
+ __asm__ __volatile__(
+ ".set\tmips64\n\t"
+ "move $9, %2\n"
+ /* "mfcr $8, $9\n" */
+ ".word 0x71280018\n"
+ "dsrl32 %0, $8, 0\n\t"
+ "dsll32 $8, $8, 0\n\t"
+ "dsrl32 %1, $8, 0\n\t"
+ ".set mips0"
+ : "=r" (high), "=r"(low)
+ : "r"((block<<8)|reg)
+ : "$8", "$9"
+ );
+
+ return ( (((unsigned long long)high)<<32) | low);
+}
+
+static __inline__ void write_64bit_phnx_ctrl_reg(int block, int reg,unsigned long long value)
+{
+ __uint32_t low, high;
+ high = value >> 32;
+ low = value & 0xffffffff;
+
+ __asm__ __volatile__(
+ ".set push\n"
+ ".set noreorder\n"
+ ".set mips4\n\t"
+ /* Set up "rs" */
+ "move $9, %0\n"
+
+ /* Store 64 bit value in "rt" */
+ "dsll32 $10, %1, 0 \n\t"
+ "dsll32 $8, %2, 0 \n\t"
+ "dsrl32 $8, $8, 0 \n\t"
+ "or $10, $8, $8 \n\t"
+
+ ".word 0x71280019\n" /* mtcr $8, $9 */
+
+ ".set pop\n"
+
+ : /* No outputs */
+ : "r"((block<<8)|reg), "r" (high), "r" (low)
+ : "$8", "$9", "$10"
+ );
+}
+
+
+#endif
diff --git a/sys/mips/rmi/rootfs_list.txt b/sys/mips/rmi/rootfs_list.txt
new file mode 100644
index 0000000..5cfd2e9
--- /dev/null
+++ b/sys/mips/rmi/rootfs_list.txt
@@ -0,0 +1,676 @@
+# This is the list of files that
+# should be in your rootfs (copy it from
+# the build world nfsmount dir. When the rge0
+# driver gets fixed we should be able to start
+# using nfs mount... for now we need to use MD_ROOT
+./.cshrc
+./.profile
+./COPYRIGHT
+./bin
+./bin/cat
+./bin/chflags
+./bin/chio
+./bin/chmod
+./bin/cp
+./bin/csh
+./bin/tcsh
+./bin/date
+./bin/dd
+./bin/df
+./bin/domainname
+./bin/echo
+./bin/ed
+./bin/red
+./bin/expr
+./bin/getfacl
+./bin/hostname
+./bin/kenv
+./bin/kill
+./bin/ln
+./bin/link
+./bin/ls
+./bin/mkdir
+./bin/mv
+./bin/pax
+./bin/pkill
+./bin/pgrep
+./bin/ps
+./bin/pwd
+./bin/rcp
+./bin/realpath
+./bin/rm
+./bin/unlink
+./bin/rmail
+./bin/rmdir
+./bin/setfacl
+./bin/sh
+./bin/sleep
+./bin/stty
+./bin/sync
+./bin/test
+./bin/[
+./bin/uuidgen
+./etc
+./etc/bluetooth
+./etc/bluetooth/hcsecd.conf
+./etc/bluetooth/hosts
+./etc/bluetooth/protocols
+./etc/defaults
+./etc/defaults/bluetooth.device.conf
+./etc/defaults/devfs.rules
+./etc/defaults/periodic.conf
+./etc/defaults/rc.conf
+./etc/devd
+./etc/devd/asus.conf
+./etc/gnats
+./etc/gnats/freefall
+./etc/gss
+./etc/gss/mech
+./etc/gss/qop
+./etc/mail
+./etc/mail/mailer.conf
+./etc/mail/freebsd.mc
+./etc/mail/freebsd.cf
+./etc/mail/freebsd.submit.mc
+./etc/mail/freebsd.submit.cf
+./etc/mail/helpfile
+./etc/mail/sendmail.cf
+./etc/mail/submit.cf
+./etc/mail/Makefile
+./etc/mail/README
+./etc/mail/access.sample
+./etc/mail/virtusertable.sample
+./etc/mail/mailertable.sample
+./etc/mail/aliases
+./etc/mtree
+./etc/mtree/BSD.include.dist
+./etc/mtree/BSD.root.dist
+./etc/mtree/BSD.usr.dist
+./etc/mtree/BSD.var.dist
+./etc/mtree/BSD.sendmail.dist
+./etc/mtree/BIND.chroot.dist
+./etc/pam.d
+./etc/pam.d/README
+./etc/pam.d/atrun
+./etc/pam.d/cron
+./etc/pam.d/ftpd
+./etc/pam.d/imap
+./etc/pam.d/kde
+./etc/pam.d/login
+./etc/pam.d/other
+./etc/pam.d/passwd
+./etc/pam.d/pop3
+./etc/pam.d/rsh
+./etc/pam.d/sshd
+./etc/pam.d/su
+./etc/pam.d/system
+./etc/pam.d/telnetd
+./etc/pam.d/xdm
+./etc/pam.d/ftp
+./etc/periodic
+./etc/periodic/daily
+./etc/periodic/daily/100.clean-disks
+./etc/periodic/daily/110.clean-tmps
+./etc/periodic/daily/120.clean-preserve
+./etc/periodic/daily/200.backup-passwd
+./etc/periodic/daily/330.news
+./etc/periodic/daily/400.status-disks
+./etc/periodic/daily/404.status-zfs
+./etc/periodic/daily/405.status-ata-raid
+./etc/periodic/daily/406.status-gmirror
+./etc/periodic/daily/407.status-graid3
+./etc/periodic/daily/408.status-gstripe
+./etc/periodic/daily/409.status-gconcat
+./etc/periodic/daily/420.status-network
+./etc/periodic/daily/450.status-security
+./etc/periodic/daily/999.local
+./etc/periodic/daily/310.accounting
+./etc/periodic/daily/470.status-named
+./etc/periodic/daily/300.calendar
+./etc/periodic/daily/130.clean-msgs
+./etc/periodic/daily/480.status-ntpd
+./etc/periodic/daily/140.clean-rwho
+./etc/periodic/daily/430.status-rwho
+./etc/periodic/daily/150.clean-hoststat
+./etc/periodic/daily/210.backup-aliases
+./etc/periodic/daily/440.status-mailq
+./etc/periodic/daily/460.status-mail-rejects
+./etc/periodic/daily/500.queuerun
+./etc/periodic/monthly
+./etc/periodic/monthly/999.local
+./etc/periodic/monthly/200.accounting
+./etc/periodic/security
+./etc/periodic/security/100.chksetuid
+./etc/periodic/security/200.chkmounts
+./etc/periodic/security/300.chkuid0
+./etc/periodic/security/400.passwdless
+./etc/periodic/security/410.logincheck
+./etc/periodic/security/700.kernelmsg
+./etc/periodic/security/800.loginfail
+./etc/periodic/security/900.tcpwrap
+./etc/periodic/security/security.functions
+./etc/periodic/security/510.ipfdenied
+./etc/periodic/security/500.ipfwdenied
+./etc/periodic/security/550.ipfwlimit
+./etc/periodic/security/520.pfdenied
+./etc/periodic/weekly
+./etc/periodic/weekly/340.noid
+./etc/periodic/weekly/999.local
+./etc/periodic/weekly/310.locate
+./etc/periodic/weekly/320.whatis
+./etc/periodic/weekly/330.catman
+./etc/periodic/weekly/400.status-pkg
+./etc/ppp
+./etc/ppp/ppp.conf
+./etc/rc.d
+./etc/rc.d/DAEMON
+./etc/rc.d/FILESYSTEMS
+./etc/rc.d/LOGIN
+./etc/rc.d/NETWORKING
+./etc/rc.d/SERVERS
+./etc/rc.d/abi
+./etc/rc.d/accounting
+./etc/rc.d/addswap
+./etc/rc.d/adjkerntz
+./etc/rc.d/amd
+./etc/rc.d/apm
+./etc/rc.d/apmd
+./etc/rc.d/archdep
+./etc/rc.d/atm1
+./etc/rc.d/atm2
+./etc/rc.d/atm3
+./etc/rc.d/auditd
+./etc/rc.d/bgfsck
+./etc/rc.d/bluetooth
+./etc/rc.d/bootparams
+./etc/rc.d/bridge
+./etc/rc.d/bthidd
+./etc/rc.d/ccd
+./etc/rc.d/cleanvar
+./etc/rc.d/cleartmp
+./etc/rc.d/cron
+./etc/rc.d/ddb
+./etc/rc.d/defaultroute
+./etc/rc.d/devd
+./etc/rc.d/devfs
+./etc/rc.d/dhclient
+./etc/rc.d/dmesg
+./etc/rc.d/dumpon
+./etc/rc.d/encswap
+./etc/rc.d/faith
+./etc/rc.d/fsck
+./etc/rc.d/ftp-proxy
+./etc/rc.d/ftpd
+./etc/rc.d/gbde
+./etc/rc.d/geli
+./etc/rc.d/geli2
+./etc/rc.d/gssd
+./etc/rc.d/hcsecd
+./etc/rc.d/hostapd
+./etc/rc.d/hostid
+./etc/rc.d/hostid_save
+./etc/rc.d/hostname
+./etc/rc.d/inetd
+./etc/rc.d/initrandom
+./etc/rc.d/ip6addrctl
+./etc/rc.d/ip6fw
+./etc/rc.d/ipfilter
+./etc/rc.d/ipfs
+./etc/rc.d/ipfw
+./etc/rc.d/ipmon
+./etc/rc.d/ipnat
+./etc/rc.d/ipsec
+./etc/rc.d/ipxrouted
+./etc/rc.d/jail
+./etc/rc.d/kadmind
+./etc/rc.d/kerberos
+./etc/rc.d/keyserv
+./etc/rc.d/kldxref
+./etc/rc.d/kpasswdd
+./etc/rc.d/ldconfig
+./etc/rc.d/local
+./etc/rc.d/localpkg
+./etc/rc.d/lockd
+./etc/rc.d/lpd
+./etc/rc.d/mixer
+./etc/rc.d/motd
+./etc/rc.d/mountcritlocal
+./etc/rc.d/mountcritremote
+./etc/rc.d/mountlate
+./etc/rc.d/mdconfig
+./etc/rc.d/mdconfig2
+./etc/rc.d/mountd
+./etc/rc.d/moused
+./etc/rc.d/mroute6d
+./etc/rc.d/mrouted
+./etc/rc.d/msgs
+./etc/rc.d/named
+./etc/rc.d/natd
+./etc/rc.d/netif
+./etc/rc.d/netoptions
+./etc/rc.d/newsyslog
+./etc/rc.d/pf
+./etc/rc.d/nfscbd
+./etc/rc.d/nfsclient
+./etc/rc.d/nfsd
+./etc/rc.d/nfsserver
+./etc/rc.d/nfsuserd
+./etc/rc.d/nisdomain
+./etc/rc.d/nsswitch
+./etc/rc.d/ntpd
+./etc/rc.d/ntpdate
+./etc/rc.d/othermta
+./etc/rc.d/pflog
+./etc/rc.d/pfsync
+./etc/rc.d/powerd
+./etc/rc.d/power_profile
+./etc/rc.d/ppp
+./etc/rc.d/pppoed
+./etc/rc.d/pwcheck
+./etc/rc.d/quota
+./etc/rc.d/random
+./etc/rc.d/rarpd
+./etc/rc.d/resolv
+./etc/rc.d/rfcomm_pppd_server
+./etc/rc.d/root
+./etc/rc.d/route6d
+./etc/rc.d/routed
+./etc/rc.d/routing
+./etc/rc.d/rpcbind
+./etc/rc.d/rtadvd
+./etc/rc.d/rwho
+./etc/rc.d/savecore
+./etc/rc.d/sdpd
+./etc/rc.d/securelevel
+./etc/rc.d/sendmail
+./etc/rc.d/serial
+./etc/rc.d/sppp
+./etc/rc.d/statd
+./etc/rc.d/static_arp
+./etc/rc.d/stf
+./etc/rc.d/swap1
+./etc/rc.d/syscons
+./etc/rc.d/sysctl
+./etc/rc.d/syslogd
+./etc/rc.d/timed
+./etc/rc.d/tmp
+./etc/rc.d/ugidfw
+./etc/rc.d/var
+./etc/rc.d/virecover
+./etc/rc.d/watchdogd
+./etc/rc.d/wpa_supplicant
+./etc/rc.d/ypbind
+./etc/rc.d/yppasswdd
+./etc/rc.d/ypserv
+./etc/rc.d/ypset
+./etc/rc.d/ypupdated
+./etc/rc.d/ypxfrd
+./etc/rc.d/zfs
+./etc/rc.d/zvol
+./etc/rc.d/sshd
+./etc/rc.d/nscd
+./etc/security
+./etc/security/audit_class
+./etc/security/audit_event
+./etc/security/audit_control
+./etc/security/audit_user
+./etc/security/audit_warn
+./etc/ssh
+./etc/ssh/ssh_config
+./etc/ssh/sshd_config
+./etc/ssh/moduli
+./etc/ssl
+./etc/ssl/openssl.cnf
+./etc/auth.conf
+./etc/crontab
+./etc/devd.conf
+./etc/devfs.conf
+./etc/ddb.conf
+./etc/dhclient.conf
+./etc/disktab
+./etc/fbtab
+./etc/ftpusers
+./etc/gettytab
+./etc/group
+./etc/hosts
+./etc/hosts.allow
+./etc/hosts.equiv
+./etc/inetd.conf
+./etc/libalias.conf
+./etc/login.access
+./etc/login.conf
+./etc/mac.conf
+./etc/motd
+./etc/netconfig
+./etc/network.subr
+./etc/networks
+./etc/newsyslog.conf
+./etc/nsswitch.conf
+./etc/phones
+./etc/profile
+./etc/protocols
+./etc/rc
+./etc/rc.bsdextended
+./etc/rc.firewall
+./etc/rc.firewall6
+./etc/rc.initdiskless
+./etc/rc.sendmail
+./etc/rc.shutdown
+./etc/rc.subr
+./etc/remote
+./etc/rpc
+./etc/services
+./etc/shells
+./etc/sysctl.conf
+./etc/syslog.conf
+./etc/ttys
+./etc/amd.map
+./etc/apmd.conf
+./etc/freebsd-update.conf
+./etc/locate.rc
+./etc/hosts.lpd
+./etc/printcap
+./etc/mail.rc
+./etc/manpath.config
+./etc/ntp.conf
+./etc/nscd.conf
+./etc/portsnap.conf
+./etc/pf.os
+./etc/csh.cshrc
+./etc/csh.login
+./etc/csh.logout
+./etc/regdomain.xml
+./etc/login.conf.db
+./etc/pwd.db
+./etc/netstart
+./etc/pccard_ether
+./etc/rc.suspend
+./etc/rc.resume
+./etc/master.passwd
+./etc/nsmb.conf
+./etc/opieaccess
+./etc/spwd.db
+./etc/passwd
+./etc/dumpdates
+./etc/fstab
+./etc/rc.conf
+./etc/resolv.conf
+./etc/termcap
+./lib
+./lib/geom
+./lib/geom/geom_cache.so
+./lib/geom/geom_concat.so
+./lib/geom/geom_eli.so
+./lib/geom/geom_journal.so
+./lib/geom/geom_label.so
+./lib/geom/geom_mirror.so
+./lib/geom/geom_multipath.so
+./lib/geom/geom_nop.so
+./lib/geom/geom_part.so
+./lib/geom/geom_raid3.so
+./lib/geom/geom_shsec.so
+./lib/geom/geom_stripe.so
+./lib/geom/geom_virstor.so
+./lib/libc.so.7
+./lib/libcrypt.so.5
+./lib/libkvm.so.5
+./lib/libm.so.5
+./lib/libmd.so.5
+./lib/libncurses.so.8
+./lib/libncursesw.so.8
+./lib/libsbuf.so.5
+./lib/libutil.so.8
+./lib/libalias.so.7
+./lib/libalias_cuseeme.so
+./lib/libalias_dummy.so
+./lib/libalias_ftp.so
+./lib/libalias_irc.so
+./lib/libalias_nbt.so
+./lib/libalias_pptp.so
+./lib/libalias_skinny.so
+./lib/libalias_smedia.so
+./lib/libbegemot.so.4
+./lib/libcam.so.5
+./lib/libdevstat.so.7
+./lib/libedit.so.7
+./lib/libbsdxml.so.4
+./lib/libgeom.so.5
+./lib/libipsec.so.4
+./lib/libipx.so.5
+./lib/libjail.so.1
+./lib/libkiconv.so.4
+./lib/libpcap.so.7
+./lib/libthr.so.3
+./lib/libufs.so.5
+./lib/libz.so.5
+./lib/libgcc_s.so.1
+./lib/libreadline.so.8
+./lib/libssp.so.0
+./lib/libcrypto.so.6
+./libexec
+./libexec/ld-elf.so.1
+./libexec/ld-elf.so.1.old
+./sbin
+./sbin/adjkerntz
+./sbin/atacontrol
+./sbin/badsect
+./sbin/bsdlabel
+./sbin/camcontrol
+./sbin/ccdconfig
+./sbin/clri
+./sbin/comcontrol
+./sbin/conscontrol
+./sbin/devd
+./sbin/devfs
+./sbin/dhclient
+./sbin/dhclient-script
+./sbin/dmesg
+./sbin/dump
+./sbin/rdump
+./sbin/dumpfs
+./sbin/dumpon
+./sbin/fdisk
+./sbin/ffsinfo
+./sbin/fsck
+./sbin/fsck_ffs
+./sbin/fsck_ufs
+./sbin/fsck_4.2bsd
+./sbin/fsdb
+./sbin/fsirand
+./sbin/gbde
+./sbin/fsck_msdosfs
+./sbin/geom
+./sbin/gcache
+./sbin/gconcat
+./sbin/geli
+./sbin/gjournal
+./sbin/glabel
+./sbin/gmirror
+./sbin/gmultipath
+./sbin/gnop
+./sbin/gpart
+./sbin/graid3
+./sbin/gshsec
+./sbin/gstripe
+./sbin/gvirstor
+./sbin/ggatec
+./sbin/ggated
+./sbin/ggatel
+./sbin/growfs
+./sbin/gvinum
+./sbin/ifconfig
+./sbin/init
+./sbin/ipf
+./sbin/ipfs
+./sbin/ipfstat
+./sbin/ipftest
+./sbin/ipmon
+./sbin/ipnat
+./sbin/ippool
+./sbin/md5
+./sbin/ipfw
+./sbin/ipresend
+./sbin/iscontrol
+./sbin/kldconfig
+./sbin/kldload
+./sbin/kldstat
+./sbin/kldunload
+./sbin/ldconfig
+./sbin/rmd160
+./sbin/sha1
+./sbin/sha256
+./sbin/mdconfig
+./sbin/mdmfs
+./sbin/mount_mfs
+./sbin/mknod
+./sbin/mksnap_ffs
+./sbin/mount
+./sbin/mount_cd9660
+./sbin/mount_msdosfs
+./sbin/mount_nfs
+./sbin/mount_newnfs
+./sbin/mount_ntfs
+./sbin/mount_nullfs
+./sbin/mount_udf
+./sbin/mount_unionfs
+./sbin/natd
+./sbin/ddb
+./sbin/newfs
+./sbin/newfs_msdos
+./sbin/nfsiod
+./sbin/nos-tun
+./sbin/pfctl
+./sbin/pflogd
+./sbin/ping
+./sbin/ping6
+./sbin/quotacheck
+./sbin/rcorder
+./sbin/reboot
+./sbin/nextboot
+./sbin/halt
+./sbin/fastboot
+./sbin/fasthalt
+./sbin/recoverdisk
+./sbin/restore
+./sbin/rrestore
+./sbin/route
+./sbin/routed
+./sbin/rtquery
+./sbin/rtsol
+./sbin/savecore
+./sbin/setkey
+./sbin/shutdown
+./sbin/spppcontrol
+./sbin/swapon
+./sbin/swapoff
+./sbin/swapctl
+./sbin/sysctl
+./sbin/tunefs
+./sbin/umount
+./sbin/init.bak
+./var
+./var/crash
+./var/crash/minfree
+./var/db
+./var/db/locate.database
+./var/log
+./var/log/sendmail.st
+./var/named
+./var/named/etc
+./var/named/etc/namedb
+./var/named/etc/namedb/master
+./var/named/etc/namedb/master/empty.db
+./var/named/etc/namedb/master/localhost-forward.db
+./var/named/etc/namedb/master/localhost-reverse.db
+./var/named/etc/namedb/named.conf
+./var/named/etc/namedb/named.root
+./var/yp
+./var/yp/Makefile.dist
+./var/run
+./var/cron
+./var/cron/tabs
+./root
+./root/.k5login
+./root/.profile
+./root/.cshrc
+./root/.login
+./list
+./dev
+./usr
+./usr/sbin
+./usr/sbin/newsyslog
+./usr/sbin/syslogd
+./usr/sbin/ip6addrctl
+./usr/sbin/sendmail
+./usr/sbin/cron
+./usr/lib
+./usr/lib/libpam.so.5
+./usr/lib/libpam.so
+./usr/lib/pam_opie.so.5
+./usr/lib/libbsm.so.3
+./usr/lib/libbsm.so
+./usr/lib/pam_chroot.so.5
+./usr/lib/pam_tacplus.so.5
+./usr/lib/pam_ssh.so.5
+./usr/lib/pam_self.so.5
+./usr/lib/pam_securetty.so.5
+./usr/lib/pam_rootok.so.5
+./usr/lib/pam_rhosts.so.5
+./usr/lib/pam_radius.so.5
+./usr/lib/pam_permit.so.5
+./usr/lib/pam_passwdqc.so.5
+./usr/lib/libcom_err.so.5
+./usr/lib/libcom_err.so
+./usr/lib/pam_opieaccess.so.5
+./usr/lib/pam_nologin.so.5
+./usr/lib/libc.so.7
+./usr/lib/pam_login_access.so.5
+./usr/lib/pam_lastlog.so.5
+./usr/lib/pam_ksu.so.5
+./usr/lib/pam_krb5.so.5
+./usr/lib/pam_guest.so.5
+./usr/lib/pam_group.so.5
+./usr/lib/pam_ftpusers.so.5
+./usr/lib/pam_exec.so.5
+./usr/lib/pam_echo.so.5
+./usr/lib/pam_deny.so.5
+./usr/lib/pam_unix.so.5
+./usr/lib/pam_chroot.so
+./usr/lib/libopie.so
+./usr/lib/pam_deny.so
+./usr/lib/pam_echo.so
+./usr/lib/pam_exec.so
+./usr/lib/pam_ftpusers.so
+./usr/lib/pam_group.so
+./usr/lib/pam_guest.so
+./usr/lib/pam_krb5.so
+./usr/lib/pam_ksu.so
+./usr/lib/pam_lastlog.so
+./usr/lib/pam_login_access.so
+./usr/lib/pam_nologin.so
+./usr/lib/pam_opie.so
+./usr/lib/pam_opieaccess.so
+./usr/lib/pam_passwdqc.so
+./usr/lib/pam_permit.so
+./usr/lib/pam_radius.so
+./usr/lib/pam_rhosts.so
+./usr/lib/pam_rootok.so
+./usr/lib/pam_securetty.so
+./usr/lib/pam_self.so
+./usr/lib/pam_ssh.so
+./usr/lib/pam_tacplus.so
+./usr/lib/pam_unix.so
+./usr/lib/libmd.so.5
+./usr/lib/libbz2.so.4
+./usr/lib/libgnuregex.so.5
+./usr/lib/libypclnt.so.4
+./usr/bin
+./usr/bin/mktemp
+./usr/bin/login
+./usr/bin/uname
+./usr/bin/awk
+./usr/bin/logger
+./usr/bin/grep
+./usr/bin/ftp
+./usr/libexec
+./usr/libexec/getty
diff --git a/sys/mips/rmi/shared_structs.h b/sys/mips/rmi/shared_structs.h
new file mode 100755
index 0000000..6e5ecd4
--- /dev/null
+++ b/sys/mips/rmi/shared_structs.h
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#ifndef _SHARED_STRUCTS_H
+#define _SHARED_STRUCTS_H
+
+/* If you make any changes to the below structs, shared_structs_offsets.h
+ * should be regenerated
+ */
+#define BOOT1_INFO_VERSION 0x0001
+
+struct boot1_info {
+ uint64_t boot_level;
+ uint64_t io_base;
+ uint64_t output_device;
+ uint64_t uart_print;
+ uint64_t led_output;
+ uint64_t init;
+ uint64_t exit;
+ uint64_t warm_reset;
+ uint64_t wakeup;
+ uint64_t cpu_online_map;
+ uint64_t master_reentry_sp;
+ uint64_t master_reentry_gp;
+ uint64_t master_reentry_fn;
+ uint64_t slave_reentry_fn;
+ uint64_t magic_dword;
+ uint64_t uart_putchar;
+ uint64_t size;
+ uint64_t uart_getchar;
+ uint64_t nmi_handler;
+ uint64_t psb_version;
+ uint64_t mac_addr;
+ uint64_t cpu_frequency;
+ uint64_t board_version;
+ uint64_t malloc;
+ uint64_t free;
+ uint64_t alloc_pbuf;
+ uint64_t free_pbuf;
+ uint64_t psb_os_cpu_map;
+ uint64_t userapp_cpu_map;
+ uint64_t wakeup_os;
+ uint64_t psb_mem_map;
+ uint64_t board_major_version;
+ uint64_t board_minor_version;
+ uint64_t board_manf_revision;
+ uint64_t board_serial_number;
+ uint64_t psb_physaddr_map;
+};
+
+extern struct boot1_info xlr_boot1_info;
+
+
+/* This structure is passed to all applications launched from the linux
+ loader through K0 register
+ */
+#define XLR_LOADER_INFO_MAGIC 0x600ddeed
+struct xlr_loader_info {
+ uint32_t magic;
+ /* xlr_loader_shared_struct_t for CPU 0 will start here */
+ unsigned long sh_mem_start;
+ /* Size of the shared memory b/w linux apps and rmios apps */
+ uint32_t app_sh_mem_size;
+};
+
+/* Boot loader uses the linux mips convention */
+#define BOOT1_MEMMAP_MAX 32
+
+enum xlr_phys_memmap_t {
+ BOOT1_MEM_RAM = 1, BOOT1_MEM_ROM_DATA, BOOT1_MEM_RESERVED
+};
+
+struct xlr_boot1_mem_map {
+ uint32_t num_entries;
+ struct {
+ uint64_t addr;
+ uint64_t size;
+ uint32_t type;
+ uint32_t pad;
+ } physmem_map[BOOT1_MEMMAP_MAX];
+};
+
+
+#endif
diff --git a/sys/mips/rmi/shared_structs_func.h b/sys/mips/rmi/shared_structs_func.h
new file mode 100755
index 0000000..be96414
--- /dev/null
+++ b/sys/mips/rmi/shared_structs_func.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+/* DO NOT EDIT THIS FILE
+ * This file has been autogenerated by ./gen_struct_offsets
+ */
+#ifndef _SHARED_STRUCTS_FUNC_H
+#define _SHARED_STRUCTS_FUNC_H
+
+/* struct boot1_info function prototypes */
+#define boot1_info_uart_print_func(info_ptr, ...) ((void (*)(const char *, ...))(unsigned long)(info_ptr->uart_print))( __VA_ARGS__ )
+#define boot1_info_led_output_func(info_ptr, ...) ((void (*)(int))(unsigned long)(info_ptr->led_output))( __VA_ARGS__ )
+#define boot1_info_init_func(info_ptr, ...) ((void (*)(void))(unsigned long)(info_ptr->init))( __VA_ARGS__ )
+#define boot1_info_exit_func(info_ptr, ...) ((void (*)(void))(unsigned long)(info_ptr->exit))( __VA_ARGS__ )
+#define boot1_info_warm_reset_func(info_ptr, ...) ((void (*)(void))(unsigned long)(info_ptr->warm_reset))( __VA_ARGS__ )
+#define boot1_info_wakeup_func(info_ptr, ...) ((int (*)(void *, void *, unsigned int))(unsigned long)(info_ptr->wakeup))( __VA_ARGS__ )
+#define boot1_info_master_reentry_fn_func(info_ptr, ...) ((void (*)(void *))(unsigned long)(info_ptr->master_reentry_fn))( __VA_ARGS__ )
+#define boot1_info_slave_reentry_fn_func(info_ptr, ...) ((void (*)(void *))(unsigned long)(info_ptr->slave_reentry_fn))( __VA_ARGS__ )
+#define boot1_info_uart_putchar_func(info_ptr, ...) ((void (*)(char))(unsigned long)(info_ptr->uart_putchar))( __VA_ARGS__ )
+#define boot1_info_uart_getchar_func(info_ptr, ...) ((char (*)(void))(unsigned long)(info_ptr->uart_getchar))( __VA_ARGS__ )
+#define boot1_info_malloc_func(info_ptr, ...) ((void *(*)(size_t))(unsigned long)(info_ptr->malloc))( __VA_ARGS__ )
+#define boot1_info_free_func(info_ptr, ...) ((void (*)(void *))(unsigned long)(info_ptr->free))( __VA_ARGS__ )
+#define boot1_info_alloc_pbuf_func(info_ptr, ...) ((struct packet *(*)(void))(unsigned long)(info_ptr->alloc_pbuf))( __VA_ARGS__ )
+#define boot1_info_free_pbuf_func(info_ptr, ...) ((void (*)(struct packet *))(unsigned long)(info_ptr->free_pbuf))( __VA_ARGS__ )
+#define boot1_info_wakeup_os_func(info_ptr, ...) ((int (*)(void *, void *, unsigned int))(unsigned long)(info_ptr->wakeup_os))( __VA_ARGS__ )
+
+
+#endif
diff --git a/sys/mips/rmi/shared_structs_offsets.h b/sys/mips/rmi/shared_structs_offsets.h
new file mode 100755
index 0000000..605c735
--- /dev/null
+++ b/sys/mips/rmi/shared_structs_offsets.h
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+/* DO NOT EDIT THIS FILE
+ * This file has been autogenerated by ./gen_struct_offsets
+ */
+#ifndef _SHARED_STRUCTS_OFFSETS_H
+#define _SHARED_STRUCTS_OFFSETS_H
+
+/* struct boot1_info offsets */
+#define boot1_info_boot_level_off 0
+#define boot1_info_io_base_off 8
+#define boot1_info_output_device_off 16
+#define boot1_info_uart_print_off 24
+#define boot1_info_led_output_off 32
+#define boot1_info_init_off 40
+#define boot1_info_exit_off 48
+#define boot1_info_warm_reset_off 56
+#define boot1_info_wakeup_off 64
+#define boot1_info_cpu_online_map_off 72
+#define boot1_info_master_reentry_sp_off 80
+#define boot1_info_master_reentry_gp_off 88
+#define boot1_info_master_reentry_fn_off 96
+#define boot1_info_slave_reentry_fn_off 104
+#define boot1_info_magic_dword_off 112
+#define boot1_info_uart_putchar_off 120
+#define boot1_info_size_off 128
+#define boot1_info_uart_getchar_off 136
+#define boot1_info_nmi_handler_off 144
+#define boot1_info_psb_version_off 152
+#define boot1_info_mac_addr_off 160
+#define boot1_info_cpu_frequency_off 168
+#define boot1_info_board_version_off 176
+#define boot1_info_malloc_off 184
+#define boot1_info_free_off 192
+#define boot1_info_alloc_pbuf_off 200
+#define boot1_info_free_pbuf_off 208
+#define boot1_info_psb_os_cpu_map_off 216
+#define boot1_info_userapp_cpu_map_off 224
+#define boot1_info_wakeup_os_off 232
+#define boot1_info_psb_mem_map_off 240
+
+/* struct boot1_info size */
+#define boot1_info_size 248
+
+/* boot1_info version */
+#define boot1_info_version 1
+
+
+#endif
diff --git a/sys/mips/rmi/std.xlr b/sys/mips/rmi/std.xlr
new file mode 100644
index 0000000..c6221b9
--- /dev/null
+++ b/sys/mips/rmi/std.xlr
@@ -0,0 +1,10 @@
+# $FreeBSD$
+files "../rmi/files.xlr"
+
+#
+# XXXMIPS: It's a stub, isn't it?
+#
+cpu CPU_MIPS4KC
+option NOFPU
+# Kludge for now
+options TARGET_XLR_XLS
diff --git a/sys/mips/rmi/tick.c b/sys/mips/rmi/tick.c
new file mode 100644
index 0000000..aaeb0e9
--- /dev/null
+++ b/sys/mips/rmi/tick.c
@@ -0,0 +1,113 @@
+/*-
+ * Copyright (c) 2006-2009 RMI Corporation
+ * Copyright (c) 2006 Bruce M. Simpson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Simple driver for the 32-bit interval counter built in to all
+ * MIPS32 CPUs.
+ * XXX: For calibration this either needs an external clock, or
+ * to be explicitly told what the frequency is.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <sys/kernel.h>
+#include <sys/power.h>
+#include <sys/smp.h>
+#include <machine/clock.h>
+#include <machine/locore.h>
+#include <machine/md_var.h>
+#include <machine/hwfunc.h>
+
+
+struct timecounter counter_timecounter = {
+ platform_get_timecount, /* get_timecount */
+ 0, /* no poll_pps */
+ ~0u, /* counter_mask */
+ 0, /* frequency */
+ "MIPS32", /* name */
+ 800, /* quality (adjusted in code) */
+};
+
+void tick_init(void);
+
+
+void
+tick_init(void)
+{
+ counter_freq = platform_get_frequency();
+ if (bootverbose)
+ printf("MIPS32 clock: %u MHz", cpu_clock);
+
+ counter_timecounter.tc_frequency = counter_freq;
+ tc_init(&counter_timecounter);
+}
+
+
+void
+cpu_startprofclock(void)
+{
+ /* nothing to do */
+}
+
+void
+cpu_stopprofclock(void)
+{
+ /* nothing to do */
+}
+
+
+static int
+sysctl_machdep_counter_freq(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ uint64_t freq;
+
+ /*
+ * RRS wonders if this will really work. You don't change the req of
+ * the system here, it would require changes to the RMI PIC in order
+ * to get the TC to run at a differrent frequency.
+ */
+
+ if (counter_timecounter.tc_frequency == 0)
+ return (EOPNOTSUPP);
+ freq = counter_freq;
+ error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
+ if (error == 0 && req->newptr != NULL) {
+ counter_freq = freq;
+ counter_timecounter.tc_frequency = counter_freq;
+ }
+ return (error);
+}
+
+SYSCTL_PROC(_machdep, OID_AUTO, counter_freq, CTLTYPE_QUAD | CTLFLAG_RW,
+ 0, sizeof(u_int), sysctl_machdep_counter_freq, "IU", "");
diff --git a/sys/mips/rmi/uart_bus_xlr_iodi.c b/sys/mips/rmi/uart_bus_xlr_iodi.c
new file mode 100644
index 0000000..33f918a
--- /dev/null
+++ b/sys/mips/rmi/uart_bus_xlr_iodi.c
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 2006 Raza Microelectronics
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/uart/uart_bus_iodi.c,v 1.6.2.5 2006/02/15 09:16:01 marius Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+#include <mips/rmi/iomap.h>
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+
+static int uart_iodi_probe(device_t dev);
+
+static device_method_t uart_iodi_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, uart_iodi_probe),
+ DEVMETHOD(device_attach, uart_bus_attach),
+ DEVMETHOD(device_detach, uart_bus_detach),
+ {0, 0}
+};
+
+static driver_t uart_iodi_driver = {
+ uart_driver_name,
+ uart_iodi_methods,
+ sizeof(struct uart_softc),
+};
+
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+static int
+uart_iodi_probe(device_t dev)
+{
+ struct uart_softc *sc;
+ sc = device_get_softc(dev);
+ sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
+ sc->sc_class = &uart_ns8250_class;
+ bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
+ sc->sc_sysdev->bas.bst = rmi_bus_space;
+ sc->sc_sysdev->bas.bsh = MIPS_PHYS_TO_KSEG1(XLR_UART0ADDR);
+ sc->sc_bas.bst = rmi_bus_space;
+ sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(XLR_UART0ADDR);
+ /* regshft = 2, rclk = 66000000, rid = 0, chan = 0 */
+ return (uart_bus_probe(dev, 2, 66000000, 0, 0));
+}
+
+DRIVER_MODULE(uart, iodi, uart_iodi_driver, uart_devclass, 0, 0);
diff --git a/sys/mips/rmi/uart_cpu_mips_xlr.c b/sys/mips/rmi/uart_cpu_mips_xlr.c
new file mode 100644
index 0000000..816dec2
--- /dev/null
+++ b/sys/mips/rmi/uart_cpu_mips_xlr.c
@@ -0,0 +1,84 @@
+/*-
+ * Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: uart_cpu_mips_xlr.c,v 1.5 2008-07-16 20:22:39 jayachandranc Exp $
+ */
+/*
+ * Skeleton of this file was based on respective code for ARM
+ * code written by Olivier Houchard.
+ */
+/*
+ * XLRMIPS: This file is hacked from arm/...
+ */
+#include "opt_uart.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <mips/rmi/iomap.h>
+
+bus_space_tag_t uart_bus_space_io;
+bus_space_tag_t uart_bus_space_mem;
+
+int
+uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
+{
+ return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
+}
+
+
+int
+uart_cpu_getdev(int devtype, struct uart_devinfo *di)
+{
+ di->ops = uart_getops(&uart_ns8250_class);
+ di->bas.chan = 0;
+ di->bas.bst = rmi_bus_space;
+ di->bas.bsh = MIPS_PHYS_TO_KSEG1(XLR_UART0ADDR);
+
+ di->bas.regshft = 2;
+ /* divisor = rclk / (baudrate * 16); */
+ di->bas.rclk = 66000000;
+ di->baudrate = 0;
+ di->databits = 8;
+ di->stopbits = 1;
+ di->parity = UART_PARITY_NONE;
+
+ uart_bus_space_io = NULL;
+ uart_bus_space_mem = rmi_bus_space;
+ return (0);
+}
diff --git a/sys/mips/rmi/xlr_boot1_console.c b/sys/mips/rmi/xlr_boot1_console.c
new file mode 100644
index 0000000..88cefcf
--- /dev/null
+++ b/sys/mips/rmi/xlr_boot1_console.c
@@ -0,0 +1,113 @@
+/*-
+ * Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: xlr_boot1_console.c,v 1.6 2008-07-16 20:22:49 jayachandranc Exp $
+ */
+/*
+ * Adapted for XLR bootloader
+ * RMi
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_comconsole.h"
+
+#include <sys/param.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/cons.h>
+#include <sys/consio.h>
+#include <sys/tty.h>
+
+#include <mips/rmi/xlrconfig.h>
+#include <mips/rmi/shared_structs.h>
+#include <mips/rmi/shared_structs_func.h>
+
+#include <ddb/ddb.h>
+
+#if 0
+static cn_probe_t xlr_boot1_cnprobe;
+static cn_init_t xlr_boot1_cninit;
+static cn_term_t xlr_boot1_cnterm;
+static cn_getc_t xlr_boot1_cngetc;
+static cn_checkc_t xlr_boot1_cncheckc;
+static cn_putc_t xlr_boot1_cnputc;
+
+CONS_DRIVER(xlrboot, xlr_boot1_cnprobe, xlr_boot1_cninit, xlr_boot1_cnterm, xlr_boot1_cngetc,
+ xlr_boot1_cncheckc, xlr_boot1_cnputc, NULL);
+
+/*
+ * Device gets probed. Firmwire should be checked here probably.
+ */
+static void
+xlr_boot1_cnprobe(struct consdev *cp)
+{
+ cp->cn_pri = CN_NORMAL;
+ cp->cn_tp = NULL;
+ cp->cn_arg = NULL; /* softc */
+ cp->cn_unit = -1; /* ? */
+ cp->cn_flags = 0;
+}
+
+/*
+ * Initialization.
+ */
+static void
+xlr_boot1_cninit(struct consdev *cp)
+{
+ sprintf(cp->cn_name, "boot1");
+}
+
+static void
+xlr_boot1_cnterm(struct consdev *cp)
+{
+ cp->cn_pri = CN_DEAD;
+ cp->cn_flags = 0;
+ return;
+}
+
+static int
+xlr_boot1_cngetc(struct consdev *cp)
+{
+ return boot1_info_uart_getchar_func(&xlr_boot1_info);
+}
+
+static void
+xlr_boot1_cnputc(struct consdev *cp, int c)
+{
+ boot1_info_uart_putchar_func(&xlr_boot1_info, c);
+}
+
+static int
+xlr_boot1_cncheckc(struct consdev *cp)
+{
+ return 0;
+}
+
+#endif
diff --git a/sys/mips/rmi/xlr_csum_nocopy.S b/sys/mips/rmi/xlr_csum_nocopy.S
new file mode 100644
index 0000000..8b51a7f
--- /dev/null
+++ b/sys/mips/rmi/xlr_csum_nocopy.S
@@ -0,0 +1,217 @@
+#include <machine/asm.h>
+
+
+/*
+ * a0: source address
+ * a1: length of the area to checksum
+ * a2: partial checksum
+ * a3: dst
+ */
+
+#define src a0
+#define dst a3
+#define sum v0
+
+ .text
+ .set noreorder
+
+ .macro CSUM_BIGCHUNK_AND_COPY offset
+ pref 0, (\offset+0x0)(a0)
+ ld t0, (\offset+0x00)(a0)
+ ld t1, (\offset+0x08)(a0)
+ .word 0x70481038 /*daddwc v0, v0, t0 */
+ .word 0x70491038 /*daddwc v0, v0, t1 */
+ ld t0, (\offset + 0x10)(a0)
+ ld t1, (\offset + 0x18)(a0)
+ .word 0x70481038 /* daddwc v0, v0, t0 */
+ .word 0x70491038 /*daddwc v0, v0, t1 */
+ .endm
+
+small_csumcpy: /* unknown src alignment and < 8 bytes to go */
+ move a1, t2
+
+ andi t0, a1, 4
+ beqz t0, 1f
+ andi t0, a1, 2
+
+ ulw t1, (src) /* Still a full word to go */
+ daddiu src, 4
+ .word 0x70491038 /*daddwc v0, v0, t1 */
+
+1: move t1, zero
+ beqz t0, 1f
+ andi t0, a1, 1
+
+ ulhu t1, (src) /* Still a halfword to go */
+ daddiu src, 2
+
+1: beqz t0, 1f
+ sll t1, t1, 16
+
+ lbu t2, (src)
+ nop
+
+#ifdef __MIPSEB__
+ sll t2, t2, 8
+#endif
+ or t1, t2
+
+1: .word 0x70491038 /*daddwc v0, v0, t1 */
+
+ .word 0x70461038 /*daddwc v0, v0, a2 */
+ .word 0x70401038 /*daddwc v0, v0, $0 */
+
+ /* Ideally at this point of time the status flag must be cleared */
+
+ dsll32 v1, sum, 0
+ .word 0x70431038 /*daddwc v0, v0, v1 */
+ dsrl32 sum, sum, 0
+ .word 0x70401038 /*daddwc v0, v0, zero */
+
+ /* fold the checksum */
+ sll v1, sum, 16
+ addu sum, v1
+ sltu v1, sum, v1
+ srl sum, sum, 16
+ addu sum, v1
+1:
+ .set reorder
+ jr ra
+ .set noreorder
+
+/* ------------------------------------------------------------------ */
+
+ .align 5
+LEAF(xlr_csum_partial_nocopy)
+ move sum, zero
+ move t7, zero
+
+ sltiu t8, a1, 0x8
+ bnez t8, small_csumcpy /* < 8 bytes to copy */
+ move t2, a1
+
+ beqz a1, out
+ andi t7, src, 0x1 /* odd buffer? */
+
+hword_align:
+ beqz t7, word_align
+ andi t8, src, 0x2
+
+ lbu t0, (src)
+ dsubu a1, a1, 0x1
+ .word 0x70481038 /*daddwc v0, v0, t0 */
+ daddu src, src, 0x1
+ andi t8, src, 0x2
+
+word_align:
+ beqz t8, dword_align
+ sltiu t8, a1, 56
+
+ lhu t0, (src)
+ dsubu a1, a1, 0x2
+ .word 0x70481038 /*daddwc v0, v0, t0 */
+ sltiu t8, a1, 56
+ daddu src, src, 0x2
+
+dword_align:
+ bnez t8, do_end_words
+ move t8, a1
+
+ andi t8, src, 0x4
+ beqz t8, qword_align
+ andi t8, src, 0x8
+
+ lw t0, 0x00(src)
+ dsubu a1, a1, 0x4
+ .word 0x70481038 /*daddwc v0, v0, t0 */
+ daddu src, src, 0x4
+ andi t8, src, 0x8
+
+qword_align:
+ beqz t8, oword_align
+ andi t8, src, 0x10
+
+ ld t0, 0x00(src)
+ dsubu a1, a1, 0x8
+ .word 0x70481038 /*daddwc v0, v0, t0 */
+ daddu src, src, 0x8
+ andi t8, src, 0x10
+
+oword_align:
+ beqz t8, begin_movement
+ dsrl t8, a1, 0x7
+
+ ld t3, 0x08(src)
+ ld t0, 0x00(src)
+ .word 0x704b1038 /*daddwc v0, v0, t3 */
+ .word 0x70481038 /*daddwc v0, v0, t0 */
+ dsubu a1, a1, 0x10
+ daddu src, src, 0x10
+ dsrl t8, a1, 0x7
+
+begin_movement:
+ beqz t8, 1f
+ andi t2, a1, 0x40
+
+move_128bytes:
+ pref 0, 0x20(a0)
+ pref 0, 0x40(a0)
+ pref 0, 0x60(a0)
+ CSUM_BIGCHUNK_AND_COPY(0x00)
+ CSUM_BIGCHUNK_AND_COPY(0x20)
+ CSUM_BIGCHUNK_AND_COPY(0x40)
+ CSUM_BIGCHUNK_AND_COPY(0x60)
+ dsubu t8, t8, 0x01
+ bnez t8, move_128bytes /* flag */
+ daddu src, src, 0x80
+
+1:
+ beqz t2, 1f
+ andi t2, a1, 0x20
+
+move_64bytes:
+ pref 0, 0x20(a0)
+ pref 0, 0x40(a0)
+ CSUM_BIGCHUNK_AND_COPY(0x00)
+ CSUM_BIGCHUNK_AND_COPY(0x20)
+ daddu src, src, 0x40
+
+1:
+ beqz t2, do_end_words
+ andi t8, a1, 0x1c
+
+move_32bytes:
+ pref 0, 0x20(a0)
+ CSUM_BIGCHUNK_AND_COPY(0x00)
+ andi t8, a1, 0x1c
+ daddu src, src, 0x20
+
+do_end_words:
+ beqz t8, maybe_end_cruft
+ dsrl t8, t8, 0x2
+
+end_words:
+ lw t0, (src)
+ dsubu t8, t8, 0x1
+ .word 0x70481038 /*daddwc v0, v0, t0 */
+ bnez t8, end_words
+ daddu src, src, 0x4
+
+maybe_end_cruft:
+ andi t2, a1, 0x3
+
+small_memcpy:
+ j small_csumcpy; move a1, t2
+ beqz t2, out
+ move a1, t2
+
+end_bytes:
+ lb t0, (src)
+ dsubu a1, a1, 0x1
+ bnez a2, end_bytes
+ daddu src, src, 0x1
+
+out:
+ jr ra
+ move v0, sum
+ END(xlr_csum_partial_nocopy)
diff --git a/sys/mips/rmi/xlr_i2c.c b/sys/mips/rmi/xlr_i2c.c
new file mode 100644
index 0000000..d05345e
--- /dev/null
+++ b/sys/mips/rmi/xlr_i2c.c
@@ -0,0 +1,455 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/mips/xlr/xlr_i2c.c,v 1.20.8.1 2008/08/25 23:17:51 cognet Exp $");
+
+/*
+ * I2C driver for the Palm-BK3220 I2C Host adapter on the RMI XLR.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+
+#include <mips/rmi/iomap.h>
+#include <mips/include/resource.h>
+
+#include "iicbus_if.h"
+
+#define DEVTOIICBUS(dev) ((struct iicbus_device*)device_get_ivars(dev))
+
+#define I2C_PALM_CFG 0x00
+#define I2C_PALM_CLKDIV 0x01
+#define I2C_PALM_DEVADDR 0x02
+#define I2C_PALM_ADDR 0x03
+#define I2C_PALM_DATAOUT 0x04
+#define I2C_PALM_DATAIN 0x05
+#define I2C_PALM_STATUS 0x06
+#define I2C_PALM_STARTXFR 0x07
+#define I2C_PALM_BYTECNT 0x08
+#define I2C_PALM_HDSTATIM 0x09
+
+/* TEST Values!! Change as required */
+#define I2C_PALM_CFG_DEF 0x000000F8 /* 8-Bit Addr + POR Values */
+#define I2C_PALM_CLKDIV_DEF 0x14A //0x00000052
+#define I2C_PALM_HDSTATIM_DEF 0x107 //0x00000000
+
+#define I2C_PALM_STARTXFR_RD 0x00000001
+#define I2C_PALM_STARTXFR_WR 0x00000000
+
+
+#define PHOENIX_IO_I2C_0_OFFSET 0x16000
+#define PHOENIX_IO_I2C_1_OFFSET 0x17000
+
+#define ARIZONA_I2c_BUS 1
+
+int bus = 1;
+
+
+uint8_t current_slave;
+uint8_t read_address;
+static xlr_reg_t *iobase_i2c_regs;
+
+static devclass_t xlr_i2c_devclass;
+
+/*
+ * Device methods
+ */
+static int xlr_i2c_probe(device_t);
+static int xlr_i2c_attach(device_t);
+static int xlr_i2c_detach(device_t);
+
+static int xlr_i2c_start(device_t dev, u_char slave, int timeout);
+static int xlr_i2c_stop(device_t dev);
+static int xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay);
+static int xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout);
+
+
+struct xlr_i2c_softc {
+ device_t dev; /* Myself */
+ struct resource *mem_res; /* Memory resource */
+ volatile int flags;
+#define RXRDY 4
+#define TXRDY 0x10
+ int sc_started;
+ int twi_addr;
+ device_t iicbus;
+};
+
+
+#define MDELAY(a){ \
+ unsigned long local_loop = 0xfffff; \
+ while(local_loop--); \
+}\
+
+static void
+get_i2c_base(void)
+{
+ if (bus == 0)
+ iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_0_OFFSET);
+ else
+ iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_1_OFFSET);
+ return;
+}
+
+static void
+palm_write(int reg, int value)
+{
+ get_i2c_base();
+ xlr_write_reg(iobase_i2c_regs, reg, value);
+ return;
+}
+
+
+static int
+palm_read(int reg)
+{
+ uint32_t val;
+
+ get_i2c_base();
+ val = xlr_read_reg(iobase_i2c_regs, reg);
+ return ((int)val);
+}
+
+static int
+palm_addr_only(uint8_t addr, uint8_t offset)
+{
+ volatile uint32_t regVal = 0x00;
+
+ palm_write(I2C_PALM_ADDR, offset);
+ palm_write(I2C_PALM_DEVADDR, addr);
+ palm_write(I2C_PALM_CFG, 0xfa);
+ palm_write(I2C_PALM_STARTXFR, 0x02);
+ regVal = palm_read(I2C_PALM_STATUS);
+ if (regVal & 0x0008) {
+ printf("palm_addr_only: ACKERR. Aborting...\n");
+ return -1;
+ }
+ return 0;
+}
+
+
+static int
+palm_rx(uint8_t addr, uint8_t offset, uint8_t len,
+ uint8_t * buf)
+{
+ volatile uint32_t regVal = 0x00, ctr = 0x00;
+ int timeOut, numBytes = 0x00;
+
+ palm_write(I2C_PALM_CFG, 0xfa);
+ palm_write(I2C_PALM_BYTECNT, len);
+ palm_write(I2C_PALM_DEVADDR, addr);
+ //DEVADDR = 0x4c, 0x68
+ MDELAY(1);
+
+ for (numBytes = 0x00; numBytes < len; numBytes++) {
+ palm_write(I2C_PALM_ADDR, offset + numBytes);
+//I2C_PALM_ADDR:offset
+ MDELAY(1);
+ if (!ctr) {
+ /* Trigger a READ Transaction */
+ palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD);
+ ctr++;
+ }
+ /* Error Conditions [Begin] */
+ regVal = palm_read(I2C_PALM_STATUS);
+ MDELAY(1);
+ if (regVal & 0x0008) {
+ printf("palm_rx: ACKERR. Aborting...\n");
+ return -1;
+ }
+ timeOut = 10;
+ while ((regVal & 0x0030) && timeOut--) {
+ palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD);
+ regVal = palm_read(I2C_PALM_STATUS);
+ }
+ if (timeOut == 0x00) {
+ printf("palm_rx: TimedOut on Valid STARTXFR/Arbitration\n");
+ return -1;
+ }
+ timeOut = 10;
+ /* Do we have valid data from the device yet..? */
+ regVal &= 0x0004;
+ while (!regVal && timeOut--) {
+ regVal = palm_read(I2C_PALM_STATUS) & 0x0004;
+ }
+ if (timeOut == 0x00) {
+ printf("palm_rx: TimedOut Waiting for Valid Data\n");
+ return -1;
+ }
+ /* Error Conditions [End] */
+ /* Read the data */
+ buf[numBytes] = (uint8_t) palm_read(I2C_PALM_DATAIN);
+ }
+ return 0;
+}
+
+
+
+static int
+wait_for_idle(void)
+{
+ int timeOut = 0x1000;
+ volatile uint32_t regVal = 0x00;
+
+ regVal = palm_read(I2C_PALM_STATUS) & 0x0001;
+ while (regVal && timeOut--) {
+ regVal = palm_read(I2C_PALM_STATUS) & 0x0001;
+ }
+ if (timeOut == 0x00)
+ return -1; /* Timed Out */
+ else
+ return 0;
+}
+
+
+static int
+palm_tx(uint8_t addr, uint8_t offset, uint8_t * buf, uint8_t len)
+{
+ volatile uint32_t regVal = 0x00;
+ int timeOut, ctr = 0x00, numBytes = len;
+
+ for (ctr = 0x00; ctr < len; ctr++) {
+ if (wait_for_idle() < 0) {
+ printf("TimedOut on Waiting for I2C Bus Idle.\n");
+ return -EIO;
+ }
+ palm_write(I2C_PALM_CFG, 0xF8);
+ palm_write(I2C_PALM_BYTECNT, 0x00);
+ palm_write(I2C_PALM_DEVADDR, addr);
+ //0x4c, 0x68
+ palm_write(I2C_PALM_ADDR, offset + numBytes - 1);
+ //offset
+ palm_write(I2C_PALM_DATAOUT, buf[ctr]);
+ palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_WR);
+ MDELAY(1);
+
+ regVal = palm_read(I2C_PALM_STATUS);
+ MDELAY(1);
+ if (regVal & 0x0008) {
+ printf("palm_tx: ACKERR. Aborting...\n");
+ return -1;
+ }
+ timeOut = 0x1000;
+ while (!(regVal & 0x0002) && timeOut) {
+ regVal = palm_read(I2C_PALM_STATUS);
+ timeOut--;
+ }
+ if (timeOut == 0x00) {
+ printf("palm_tx: [TimeOut] SDOEMPTY Not Set\n");
+ return -1;
+ }
+ timeOut = 1000;
+ while ((regVal & 0x0030) && timeOut) {
+ palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_WR);
+ regVal = palm_read(I2C_PALM_STATUS);
+ timeOut--;
+ }
+ if (timeOut == 0x00) {
+ printf("palm_rx: TimedOut on Valid STARTXFR/Arbitration\n");
+ return -1;
+ }
+ numBytes--;
+ }
+ return 0;
+}
+
+
+
+
+
+static int
+xlr_i2c_probe(device_t dev)
+{
+ device_set_desc(dev, "I2C bus controller");
+
+ return (0);
+}
+
+
+/*
+ * We add all the devices which we know about.
+ * The generic attach routine will attach them if they are alive.
+ */
+static int
+xlr_i2c_attach(device_t dev)
+{
+ struct xlr_i2c_softc *sc;
+ int rid;
+
+ sc = device_get_softc(dev);
+ sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
+ if (sc->mem_res == NULL) {
+ printf("not able to allocate the bus resource\n");
+ }
+ if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL)
+ printf("could not allocate iicbus instance\n");
+
+ bus_generic_attach(dev);
+
+ return (0);
+}
+
+static int
+xlr_i2c_detach(device_t dev)
+{
+ bus_generic_detach(dev);
+
+ return (0);
+}
+
+/*
+static int
+xlr_i2c_add_child(device_t dev, int order, const char *name, int unit)
+{
+ printf("********* %s ******** \n", __FUNCTION__);
+ device_add_child_ordered(dev, order, name, unit);
+
+ bus_generic_attach(dev);
+
+ return (0);
+}
+*/
+
+static int
+xlr_i2c_start(device_t dev, u_char slave, int timeout)
+{
+ int error = 0;
+ struct xlr_i2c_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->sc_started = 1;
+
+ current_slave = (slave >> 1);
+ return error;
+
+}
+
+static int
+xlr_i2c_stop(device_t dev)
+{
+ int error = 0;
+
+ return error;
+
+}
+
+static int
+xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last,
+ int delay)
+{
+ int error = 0;
+
+ if (palm_addr_only(current_slave, read_address) == -1) {
+ printf("I2C ADDRONLY Phase Fail.\n");
+ return -1;
+ }
+ if (palm_rx(current_slave, read_address, len, buf) == -1) {
+ printf("I2C Read Fail.\n");
+ return -1;
+ }
+ *read = len;
+ return error;
+
+}
+
+
+static int
+xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout /* us */ )
+{
+
+ int error = 0;
+ uint8_t write_address;
+
+ if (len == 1) {
+ /* address for the next read */
+ read_address = buf[0];
+ return error;
+ }
+ if (len < 2)
+ return (-1);
+
+ write_address = buf[0];
+
+ /*
+ * for write operation, buf[0] contains the register offset and
+ * buf[1] onwards contains the value
+ */
+ palm_tx(current_slave, write_address, &buf[1], len - 1);
+
+ return error;
+
+}
+
+static int
+xlr_i2c_callback(device_t dev, int index, caddr_t *data)
+{
+ return 0;
+}
+
+static int
+xlr_i2c_repeated_start(device_t dev, u_char slave, int timeout)
+{
+ return 0;
+}
+
+
+static device_method_t xlr_i2c_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, xlr_i2c_probe),
+ DEVMETHOD(device_attach, xlr_i2c_attach),
+ DEVMETHOD(device_detach, xlr_i2c_detach),
+
+ /* iicbus interface */
+ DEVMETHOD(iicbus_callback, xlr_i2c_callback),
+ DEVMETHOD(iicbus_repeated_start, xlr_i2c_repeated_start),
+ DEVMETHOD(iicbus_start, xlr_i2c_start),
+ DEVMETHOD(iicbus_stop, xlr_i2c_stop),
+ DEVMETHOD(iicbus_write, xlr_i2c_write),
+ DEVMETHOD(iicbus_read, xlr_i2c_read),
+ {0, 0}
+};
+
+static driver_t xlr_i2c_driver = {
+ "xlr_i2c",
+ xlr_i2c_methods,
+ sizeof(struct xlr_i2c_softc),
+};
+
+DRIVER_MODULE(xlr_i2c, iodi, xlr_i2c_driver, xlr_i2c_devclass, 0, 0);
diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c
new file mode 100644
index 0000000..80827b5
--- /dev/null
+++ b/sys/mips/rmi/xlr_machdep.c
@@ -0,0 +1,726 @@
+/*-
+ * Copyright (c) 2006-2009 RMI Corporation
+ * Copyright (c) 2002-2004 Juli Mallett <jmallett@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/rtprio.h>
+#include <sys/systm.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/ktr.h>
+#include <sys/limits.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/random.h>
+#include <sys/resourcevar.h>
+#include <sys/sched.h>
+#include <sys/sysctl.h>
+#include <sys/unistd.h>
+
+#include <sys/cons.h> /* cinit() */
+#include <sys/kdb.h>
+#include <sys/reboot.h>
+#include <sys/queue.h>
+#include <sys/smp.h>
+#include <sys/timetc.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/cpuinfo.h>
+#include <machine/cpuregs.h>
+#include <machine/frame.h>
+#include <machine/hwfunc.h>
+#include <machine/md_var.h>
+#include <machine/asm.h>
+#include <machine/pmap.h>
+#include <machine/trap.h>
+#include <machine/clock.h>
+#include <machine/fls64.h>
+#include <machine/intr_machdep.h>
+#include <machine/smp.h>
+#include <mips/rmi/rmi_mips_exts.h>
+
+#include <mips/rmi/iomap.h>
+#include <mips/rmi/clock.h>
+#include <mips/rmi/msgring.h>
+#include <mips/rmi/xlrconfig.h>
+#include <mips/rmi/interrupt.h>
+#include <mips/rmi/pic.h>
+
+#ifdef XLR_PERFMON
+#include <mips/rmi/perfmon.h>
+#endif
+
+
+
+void platform_prep_smp_launch(void);
+
+unsigned long xlr_io_base = (unsigned long)(DEFAULT_XLR_IO_BASE);
+
+/* 4KB static data aread to keep a copy of the bootload env until
+ the dynamic kenv is setup */
+char boot1_env[4096];
+extern unsigned long _gp;
+int rmi_spin_mutex_safe=0;
+/*
+ * Parameters from boot loader
+ */
+struct boot1_info xlr_boot1_info;
+struct xlr_loader_info xlr_loader_info; /* FIXME : Unused */
+int xlr_run_mode;
+int xlr_argc;
+char **xlr_argv, **xlr_envp;
+uint64_t cpu_mask_info;
+uint32_t xlr_online_cpumask;
+
+#ifdef SMP
+static unsigned long xlr_secondary_gp[MAXCPU];
+static unsigned long xlr_secondary_sp[MAXCPU];
+
+#endif
+extern int mips_cpu_online_mask;
+extern int mips_cpu_logical_mask;
+uint32_t cpu_ltop_map[MAXCPU];
+uint32_t cpu_ptol_map[MAXCPU];
+uint32_t xlr_core_cpu_mask = 0x1; /* Core 0 thread 0 is always there */
+
+void
+platform_reset(void)
+{
+ /* FIXME : use proper define */
+ u_int32_t *mmio = (u_int32_t *) 0xbef18000;
+
+ printf("Rebooting the system now\n");
+ mmio[8] = 0x1;
+}
+
+void
+platform_secondary_init(void)
+{
+#ifdef SMP
+ xlr_msgring_cpu_init();
+
+ /* Setup interrupts for secondary CPUs here */
+ mips_mask_hard_irq(IPI_SMP_CALL_FUNCTION);
+ mips_mask_hard_irq(IPI_STOP);
+ mips_mask_hard_irq(IPI_RENDEZVOUS);
+ mips_mask_hard_irq(IPI_AST);
+ mips_mask_hard_irq(IRQ_TIMER);
+#ifdef XLR_PERFMON
+ mips_mask_hard_irq(IPI_PERFMON);
+#endif
+
+ return;
+#endif
+}
+
+
+int xlr_asid_pcpu = 256; /* This the default */
+int xlr_shtlb_enabled = 0;
+
+/* This function sets up the number of tlb entries available
+ to the kernel based on the number of threads brought up.
+ The ASID range also gets divided similarly.
+ THE NUMBER OF THREADS BROUGHT UP IN EACH CORE MUST BE THE SAME
+NOTE: This function will mark all 64TLB entries as available
+to the threads brought up in the core. If kernel is brought with say mask
+0x33333333, no TLBs will be available to the threads in each core.
+*/
+static void
+setup_tlb_resource(void)
+{
+ int mmu_setup;
+ int value = 0;
+ uint32_t cpu_map = xlr_boot1_info.cpu_online_map;
+ uint32_t thr_mask = cpu_map >> (xlr_cpu_id() << 2);
+ uint8_t core0 = xlr_boot1_info.cpu_online_map & 0xf;
+ uint8_t core_thr_mask;
+ int i = 0, count = 0;
+
+ /* If CPU0 did not enable shared TLB, other cores need to follow */
+ if ((xlr_cpu_id() != 0) && (xlr_shtlb_enabled == 0))
+ return;
+ /* First check if each core is brought up with the same mask */
+ for (i = 1; i < 8; i++) {
+ core_thr_mask = cpu_map >> (i << 2);
+ core_thr_mask &= 0xf;
+ if (core_thr_mask && core_thr_mask != core0) {
+ printf
+ ("Each core must be brought with same cpu mask\n");
+ printf("Cannot enabled shared TLB. ");
+ printf("Falling back to split TLB mode\n");
+ return;
+ }
+ }
+
+ xlr_shtlb_enabled = 1;
+ for (i = 0; i < 4; i++)
+ if (thr_mask & (1 << i))
+ count++;
+ switch (count) {
+ case 1:
+ xlr_asid_pcpu = 256;
+ break;
+ case 2:
+ xlr_asid_pcpu = 128;
+ value = 0x2;
+ break;
+ default:
+ xlr_asid_pcpu = 64;
+ value = 0x3;
+ break;
+ }
+
+ mmu_setup = read_32bit_phnx_ctrl_reg(4, 0);
+ mmu_setup = mmu_setup & ~0x06;
+ mmu_setup |= (value << 1);
+
+ /* turn on global mode */
+ mmu_setup |= 0x01;
+
+ write_32bit_phnx_ctrl_reg(4, 0, mmu_setup);
+
+}
+
+/*
+ * Platform specific register setup for CPUs
+ * XLR has control registers accessible with MFCR/MTCR instructions, this
+ * code initialized them from the environment variable xlr.cr of form:
+ * xlr.cr=reg:val[,reg:val]*, all values in hex.
+ * To enable shared TLB option use xlr.shtlb=1
+ */
+void
+platform_cpu_init()
+{
+ char *hw_env;
+ char *start, *end;
+ uint32_t reg, val;
+ int thr_id = xlr_thr_id();
+
+ if (thr_id == 0) {
+ if ((hw_env = getenv("xlr.shtlb")) != NULL) {
+ start = hw_env;
+ reg = strtoul(start, &end, 16);
+ if (start != end && reg != 0)
+ setup_tlb_resource();
+ } else {
+ /* By default TLB entries are shared in a core */
+ setup_tlb_resource();
+ }
+ }
+ if ((hw_env = getenv("xlr.cr")) == NULL)
+ return;
+
+ start = hw_env;
+ while (*start != '\0') {
+ reg = strtoul(start, &end, 16);
+ if (start == end) {
+ printf("Invalid value in xlr.cr %s, cannot read a hex value at %d\n",
+ hw_env, start - hw_env);
+ goto err_return;
+ }
+ if (*end != ':') {
+ printf("Invalid format in xlr.cr %s, ':' expected at pos %d\n",
+ hw_env, end - hw_env);
+ goto err_return;
+ }
+ start = end + 1;/* step over ':' */
+ val = strtoul(start, &end, 16);
+ if (start == end) {
+ printf("Invalid value in xlr.cr %s, cannot read a hex value at pos %d\n",
+ hw_env, start - hw_env);
+ goto err_return;
+ }
+ if (*end != ',' && *end != '\0') {
+ printf("Invalid format in xlr.cr %s, ',' expected at pos %d\n",
+ hw_env, end - hw_env);
+ goto err_return;
+ }
+ xlr_mtcr(reg, val);
+ if (*end == ',')
+ start = end + 1; /* skip over ',' */
+ else
+ start = end;
+ }
+ freeenv(hw_env);
+ return;
+
+err_return:
+ panic("Invalid xlr.cr setting!");
+ return;
+}
+
+
+#ifdef SMP
+extern void xlr_secondary_start(unsigned long, unsigned long, unsigned long);
+static void
+xlr_secondary_entry(void *data)
+{
+ unsigned long sp, gp;
+ unsigned int cpu = (xlr_cpu_id() << 2) + xlr_thr_id();
+
+ sp = xlr_secondary_sp[cpu];
+ gp = xlr_secondary_gp[cpu];
+
+ xlr_secondary_start((unsigned long)mips_secondary_wait, sp, gp);
+}
+
+#endif
+
+static void
+xlr_set_boot_flags(void)
+{
+ char *p;
+
+ for (p = getenv("boot_flags"); p && *p != '\0'; p++) {
+ switch (*p) {
+ case 'd':
+ case 'D':
+ boothowto |= RB_KDB;
+ break;
+ case 'g':
+ case 'G':
+ boothowto |= RB_GDB;
+ break;
+ case 'v':
+ case 'V':
+ boothowto |= RB_VERBOSE;
+ break;
+
+ case 's': /* single-user (default, supported for sanity) */
+ case 'S':
+ boothowto |= RB_SINGLE;
+ break;
+
+ default:
+ printf("Unrecognized boot flag '%c'.\n", *p);
+ break;
+ }
+ }
+
+ if (p)
+ freeenv(p);
+
+ return;
+}
+extern uint32_t _end;
+
+
+static void
+mips_init(void)
+{
+ init_param1();
+ init_param2(physmem);
+
+ /* XXX: Catch 22. Something touches the tlb. */
+
+ mips_cpu_init();
+ pmap_bootstrap();
+
+ mips_proc0_init();
+ write_c0_register32(MIPS_COP_0_OSSCRATCH, 7, pcpup->pc_curthread);
+
+ mutex_init();
+
+ PMAP_LOCK_INIT(kernel_pmap);
+
+#ifdef DDB
+#ifdef SMP
+ setup_nmi();
+#endif /* SMP */
+ kdb_init();
+ if (boothowto & RB_KDB) {
+ kdb_enter("Boot flags requested debugger", NULL);
+ }
+#endif
+}
+
+void
+platform_start(__register_t a0 __unused,
+ __register_t a1 __unused,
+ __register_t a2 __unused,
+ __register_t a3 __unused)
+{
+ vm_size_t physsz = 0;
+ int i, j;
+ struct xlr_boot1_mem_map *boot_map;
+#ifdef SMP
+ uint32_t tmp;
+ void (*wakeup) (void *, void *, unsigned int);
+
+#endif
+ /* XXX no zeroing of BSS? */
+
+ /* Initialize pcpu stuff */
+ mips_pcpu0_init();
+
+ /* XXX FIXME the code below is not 64 bit clean */
+ /* Save boot loader and other stuff from scratch regs */
+ xlr_boot1_info = *(struct boot1_info *)read_c0_register32(MIPS_COP_0_OSSCRATCH, 0);
+ cpu_mask_info = read_c0_register64(MIPS_COP_0_OSSCRATCH, 1);
+ xlr_online_cpumask = read_c0_register32(MIPS_COP_0_OSSCRATCH, 2);
+ xlr_run_mode = read_c0_register32(MIPS_COP_0_OSSCRATCH, 3);
+ xlr_argc = read_c0_register32(MIPS_COP_0_OSSCRATCH, 4);
+ xlr_argv = (char **)read_c0_register32(MIPS_COP_0_OSSCRATCH, 5);
+ xlr_envp = (char **)read_c0_register32(MIPS_COP_0_OSSCRATCH, 6);
+
+ /* TODO: Verify the magic number here */
+ /* FIXMELATER: xlr_boot1_info.magic_number */
+
+ /* initialize console so that we have printf */
+ boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */
+
+ /* clockrate used by delay, so initialize it here */
+ cpu_clock = xlr_boot1_info.cpu_frequency / 1000000;
+
+ /*
+ * Note the time counter on CPU0 runs not at system clock speed, but
+ * at PIC time counter speed (which is returned by
+ * platform_get_frequency(). Thus we do not use
+ * xlr_boot1_info.cpu_frequency here.
+ */
+ mips_timer_early_init(platform_get_frequency());
+
+ /* Init the time counter in the PIC and local putc routine*/
+ rmi_early_counter_init();
+
+ /* Init console please */
+ cninit();
+ init_static_kenv(boot1_env, sizeof(boot1_env));
+ printf("Environment (from %d args):\n", xlr_argc - 1);
+ if (xlr_argc == 1)
+ printf("\tNone\n");
+ for (i = 1; i < xlr_argc; i++) {
+ char *n;
+
+ printf("\t%s\n", xlr_argv[i]);
+ n = strsep(&xlr_argv[i], "=");
+ if (xlr_argv[i] == NULL)
+ setenv(n, "1");
+ else
+ setenv(n, xlr_argv[i]);
+ }
+
+ xlr_set_boot_flags();
+
+ /* get physical memory info from boot loader */
+ boot_map = (struct xlr_boot1_mem_map *)
+ (unsigned long)xlr_boot1_info.psb_mem_map;
+ for (i = 0, j = 0; i < boot_map->num_entries; i++, j += 2) {
+ if (boot_map->physmem_map[i].type == BOOT1_MEM_RAM) {
+ if (j == 14) {
+ printf("*** ERROR *** memory map too large ***\n");
+ break;
+ }
+ if (j == 0) {
+ /* TODO FIXME */
+ /* start after kernel end */
+ phys_avail[0] = (vm_paddr_t)
+ MIPS_KSEG0_TO_PHYS(&_end) + 0x20000;
+ /* boot loader start */
+ /* HACK to Use bootloaders memory region */
+ /* TODO FIXME */
+ if (boot_map->physmem_map[0].size == 0x0c000000) {
+ boot_map->physmem_map[0].size = 0x0ff00000;
+ }
+ phys_avail[1] = boot_map->physmem_map[0].addr +
+ boot_map->physmem_map[0].size;
+
+ } else {
+/*
+ * Can't use this code yet, because most of the fixed allocations happen from
+ * the biggest physical area. If we have more than 512M memory the kernel will try
+ * to map from the second are which is not in KSEG0 and not mapped
+ */
+ phys_avail[j] = (vm_paddr_t)
+ boot_map->physmem_map[i].addr;
+ phys_avail[j + 1] = phys_avail[j] +
+ boot_map->physmem_map[i].size;
+#if 0 /* FIXME TOD0 */
+ phys_avail[j] = phys_avail[j + 1] = 0;
+#endif
+ }
+ physsz += boot_map->physmem_map[i].size;
+ }
+ }
+
+ /* FIXME XLR TODO */
+ phys_avail[j] = phys_avail[j + 1] = 0;
+ realmem = physmem = btoc(physsz);
+
+ /* Store pcpu in scratch 5 */
+ write_c0_register32(MIPS_COP_0_OSSCRATCH, 5, pcpup);
+
+ /* Set up hz, among others. */
+ mips_init();
+
+#ifdef SMP
+ /*
+ * If thread 0 of any core is not available then mark whole core as
+ * not available
+ */
+ tmp = xlr_boot1_info.cpu_online_map;
+ for (i = 4; i < MAXCPU; i += 4) {
+ if ((tmp & (0xf << i)) && !(tmp & (0x1 << i))) {
+ /*
+ * Oopps.. thread 0 is not available. Disable whole
+ * core
+ */
+ tmp = tmp & ~(0xf << i);
+ printf("WARNING: Core %d is disabled because thread 0"
+ " of this core is not enabled.\n", i / 4);
+ }
+ }
+ xlr_boot1_info.cpu_online_map = tmp;
+
+ /* Wakeup Other cpus, and put them in bsd park code. */
+ for (i = 1, j = 1; i < 32; i++) {
+ /* Allocate stack for all other cpus from fbsd kseg0 memory. */
+ if ((1U << i) & xlr_boot1_info.cpu_online_map) {
+ xlr_secondary_gp[i] =
+ pmap_steal_memory(PAGE_SIZE);
+ if (!xlr_secondary_gp[i])
+ panic("Allocation failed for secondary cpu stacks");
+ xlr_secondary_sp[i] =
+ xlr_secondary_gp[i] + PAGE_SIZE - CALLFRAME_SIZ;
+ xlr_secondary_gp[i] = (unsigned long)&_gp;
+ /* Build ltop and ptol cpu map. */
+ cpu_ltop_map[j] = i;
+ cpu_ptol_map[i] = j;
+ if ((i & 0x3) == 0) /* store thread0 of each core */
+ xlr_core_cpu_mask |= (1 << j);
+ mips_cpu_logical_mask |= (1 << j);
+ j++;
+ }
+ }
+
+ mips_cpu_online_mask |= xlr_boot1_info.cpu_online_map;
+ wakeup = ((void (*) (void *, void *, unsigned int))
+ (unsigned long)(xlr_boot1_info.wakeup));
+ printf("Waking up CPUs 0x%llx.\n", xlr_boot1_info.cpu_online_map & ~(0x1U));
+ if (xlr_boot1_info.cpu_online_map & ~(0x1U))
+ wakeup(xlr_secondary_entry, 0,
+ (unsigned int)xlr_boot1_info.cpu_online_map);
+#endif
+
+ /* xlr specific post initialization */
+ /*
+ * The expectation is that mutex_init() is already done in
+ * mips_init() XXX NOTE: We may need to move this to SMP based init
+ * code for each CPU, later.
+ */
+ rmi_spin_mutex_safe = 1;
+ on_chip_init();
+ mips_timer_init_params(platform_get_frequency(), 0);
+ printf("Platform specific startup now completes\n");
+}
+
+void
+platform_identify(void)
+{
+ printf("Board [%d:%d], processor 0x%08x\n", (int)xlr_boot1_info.board_major_version,
+ (int)xlr_boot1_info.board_minor_version, mips_rd_prid());
+
+
+}
+
+/*
+ * XXX Maybe return the state of the watchdog in enter, and pass it to
+ * exit? Like spl().
+ */
+void
+platform_trap_enter(void)
+{
+}
+
+void
+platform_trap_exit(void)
+{
+}
+
+
+/*
+ void
+ platform_update_intrmask(int intr)
+ {
+ write_c0_eimr64(read_c0_eimr64() | (1ULL<<intr));
+ }
+*/
+
+void
+disable_msgring_int(void *arg);
+void
+enable_msgring_int(void *arg);
+void xlr_msgring_handler(struct trapframe *tf);
+void msgring_process_fast_intr(void *arg);
+
+struct msgring_ithread {
+ struct thread *i_thread;
+ u_int i_pending;
+ u_int i_flags;
+ int i_cpu;
+};
+struct msgring_ithread msgring_ithreads[MAXCPU];
+char ithd_name[MAXCPU][32];
+
+void
+msgring_process_fast_intr(void *arg)
+{
+ int cpu = PCPU_GET(cpuid);
+ volatile struct msgring_ithread *it;
+ struct proc *p;
+ struct thread *td;
+
+ /* wakeup an appropriate intr_thread for processing this interrupt */
+ it = (volatile struct msgring_ithread *)&msgring_ithreads[cpu];
+ td = it->i_thread;
+ p = td->td_proc;
+
+ /*
+ * Interrupt thread will enable the interrupts after processing all
+ * messages
+ */
+ disable_msgring_int(NULL);
+ it->i_pending = 1;
+ if (TD_AWAITING_INTR(td)) {
+ thread_lock(td);
+ CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid,
+ p->p_comm);
+ TD_CLR_IWAIT(td);
+ sched_add(td, SRQ_INTR);
+ thread_unlock(td);
+ } else {
+ CTR4(KTR_INTR, "%s: pid %d (%s): state %d",
+ __func__, p->p_pid, p->p_comm, td->td_state);
+ }
+
+}
+
+#define MIT_DEAD 4
+static void
+msgring_process(void *arg)
+{
+ volatile struct msgring_ithread *ithd;
+ struct thread *td;
+ struct proc *p;
+
+ td = curthread;
+ p = td->td_proc;
+ ithd = (volatile struct msgring_ithread *)arg;
+ KASSERT(ithd->i_thread == td,
+ ("%s:msg_ithread and proc linkage out of sync", __func__));
+
+ /* First bind this thread to the right CPU */
+ thread_lock(td);
+ sched_bind(td, ithd->i_cpu);
+ thread_unlock(td);
+
+ //printf("Started %s on CPU %d\n", __FUNCTION__, ithd->i_cpu);
+
+ while (1) {
+ if (ithd->i_flags & MIT_DEAD) {
+ CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__,
+ p->p_pid, p->p_comm);
+ kthread_exit();
+ }
+ while (ithd->i_pending) {
+ /*
+ * This might need a full read and write barrier to
+ * make sure that this write posts before any of the
+ * memory or device accesses in the handlers.
+ */
+ atomic_store_rel_int(&ithd->i_pending, 0);
+ xlr_msgring_handler(NULL);
+ }
+ if (!ithd->i_pending && !(ithd->i_flags & MIT_DEAD)) {
+ thread_lock(td);
+ sched_class(td, PRI_ITHD);
+ TD_SET_IWAIT(td);
+ thread_unlock(td);
+ enable_msgring_int(NULL);
+ mi_switch(SW_VOL, NULL);
+ }
+ }
+
+}
+void
+platform_prep_smp_launch(void)
+{
+ int cpu;
+ uint32_t cpu_mask;
+ struct msgring_ithread *ithd;
+ struct thread *td;
+ struct proc *p;
+ int error;
+
+ cpu_mask = PCPU_GET(cpumask) | PCPU_GET(other_cpus);
+
+ /* Create kernel threads for message ring interrupt processing */
+ /* Currently create one task for thread 0 of each core */
+ for (cpu = 0; cpu < MAXCPU; cpu += 1) {
+
+ if (!((1 << cpu) & cpu_mask))
+ continue;
+
+ if ((cpu_ltop_map[cpu] % 4) != 0)
+ continue;
+
+ ithd = &msgring_ithreads[cpu];
+ sprintf(ithd_name[cpu], "msg_intr%d", cpu);
+ error = kproc_create(msgring_process,
+ (void *)ithd,
+ &p,
+ (RFSTOPPED | RFHIGHPID),
+ 2,
+ ithd_name[cpu]);
+
+ if (error)
+ panic("kproc_create() failed with %d", error);
+ td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */
+
+ thread_lock(td);
+ sched_class(td, PRI_ITHD);
+ TD_SET_IWAIT(td);
+ thread_unlock(td);
+ ithd->i_thread = td;
+ ithd->i_pending = 0;
+ ithd->i_cpu = cpu;
+ CTR2(KTR_INTR, "%s: created %s", __func__, ithd_name[cpu]);
+ }
+}
diff --git a/sys/mips/rmi/xlr_pci.c b/sys/mips/rmi/xlr_pci.c
new file mode 100644
index 0000000..1ed6a7c
--- /dev/null
+++ b/sys/mips/rmi/xlr_pci.c
@@ -0,0 +1,426 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <machine/md_var.h>
+#include <mips/rmi/rmi_mips_exts.h>
+#include <machine/cpuregs.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
+#include <sys/rman.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcib_private.h>
+
+#include <mips/rmi/iomap.h>
+#include <mips/rmi/pic.h>
+#include <mips/rmi/shared_structs.h>
+#include <mips/rmi/board.h>
+#include <mips/rmi/pcibus.h>
+#include "pcib_if.h"
+
+#define LSU_CFG0_REGID 0
+#define LSU_CERRLOG_REGID 9
+#define LSU_CERROVF_REGID 10
+#define LSU_CERRINT_REGID 11
+#define SWAP32(x)\
+ (((x) & 0xff000000) >> 24) | \
+ (((x) & 0x000000ff) << 24) | \
+ (((x) & 0x0000ff00) << 8) | \
+ (((x) & 0x00ff0000) >> 8)
+
+
+/* MSI support */
+
+#define MSI_MIPS_ADDR_DEST 0x000ff000
+#define MSI_MIPS_ADDR_RH 0x00000008
+#define MSI_MIPS_ADDR_RH_OFF 0x00000000
+#define MSI_MIPS_ADDR_RH_ON 0x00000008
+#define MSI_MIPS_ADDR_DM 0x00000004
+#define MSI_MIPS_ADDR_DM_PHYSICAL 0x00000000
+#define MSI_MIPS_ADDR_DM_LOGICAL 0x00000004
+
+/* Fields in data for Intel MSI messages. */
+#define MSI_MIPS_DATA_TRGRMOD 0x00008000 /* Trigger mode */
+#define MSI_MIPS_DATA_TRGREDG 0x00000000 /* edge */
+#define MSI_MIPS_DATA_TRGRLVL 0x00008000 /* level */
+
+#define MSI_MIPS_DATA_LEVEL 0x00004000 /* Polarity. */
+#define MSI_MIPS_DATA_DEASSERT 0x00000000
+#define MSI_MIPS_DATA_ASSERT 0x00004000
+
+#define MSI_MIPS_DATA_DELMOD 0x00000700 /* Delivery Mode */
+#define MSI_MIPS_DATA_DELFIXED 0x00000000 /* fixed */
+#define MSI_MIPS_DATA_DELLOPRI 0x00000100 /* lowest priority */
+
+#define MSI_MIPS_DATA_INTVEC 0x000000ff
+
+/*
+ * Build Intel MSI message and data values from a source. AMD64 systems
+ * seem to be compatible, so we use the same function for both.
+ */
+#define MIPS_MSI_ADDR(cpu) \
+ (MSI_MIPS_ADDR_BASE | (cpu) << 12 | \
+ MSI_MIPS_ADDR_RH_OFF | MSI_MIPS_ADDR_DM_PHYSICAL)
+
+#define MIPS_MSI_DATA(irq) \
+ (MSI_MIPS_DATA_TRGRLVL | MSI_MIPS_DATA_DELFIXED | \
+ MSI_MIPS_DATA_ASSERT | (irq))
+
+struct xlr_hose_softc {
+ int junk; /* no softc */
+};
+static devclass_t pcib_devclass;
+static int pci_bus_status = 0;
+static void *pci_config_base;
+
+static uint32_t pci_cfg_read_32bit(uint32_t addr);
+static void pci_cfg_write_32bit(uint32_t addr, uint32_t data);
+
+static int
+xlr_pcib_probe(device_t dev)
+{
+ device_set_desc(dev, "xlr system bridge controller");
+
+ pci_init_resources();
+ pci_config_base = (void *)MIPS_PHYS_TO_KSEG1(DEFAULT_PCI_CONFIG_BASE);
+ pci_bus_status = 1;
+
+ return 0;
+}
+
+static int
+xlr_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t * result)
+{
+#if 0
+ device_printf(dev, "xlr_pcib_read_ivar : read ivar %d for child %s\n", which, device_get_nameunit(child));
+#endif
+ switch (which) {
+ case PCIB_IVAR_BUS:
+ *result = 0;
+ return 0;
+ }
+ return ENOENT;
+}
+
+static int
+xlr_pcib_maxslots(device_t dev)
+{
+ if (xlr_board_info.is_xls)
+ return 4;
+ else
+ return 32;
+}
+
+#define pci_cfg_offset(bus,slot,devfn,where) (((bus)<<16) + ((slot) << 11)+((devfn)<<8)+(where))
+
+static __inline__ void
+disable_and_clear_cache_error(void)
+{
+ uint64_t lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID);
+
+ lsu_cfg0 = lsu_cfg0 & ~0x2e;
+ write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0);
+ /* Clear cache error log */
+ write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0);
+}
+
+static __inline__ void
+clear_and_enable_cache_error(void)
+{
+ uint64_t lsu_cfg0 = 0;
+
+ /* first clear the cache error logging register */
+ write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0);
+ write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERROVF_REGID, 0);
+ write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRINT_REGID, 0);
+
+ lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID);
+ lsu_cfg0 = lsu_cfg0 | 0x2e;
+ write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0);
+}
+
+static uint32_t
+phoenix_pciread(u_int b, u_int s, u_int f,
+ u_int reg, int width)
+{
+ uint32_t data = 0;
+
+ if ((width == 2) && (reg & 1))
+ return 0xFFFFFFFF;
+ else if ((width == 4) && (reg & 3))
+ return 0xFFFFFFFF;
+
+ if (pci_bus_status)
+ data = pci_cfg_read_32bit(pci_cfg_offset(b, s, f, reg));
+ else
+ data = 0xFFFFFFFF;
+
+ if (width == 1)
+ return ((data >> ((reg & 3) << 3)) & 0xff);
+ else if (width == 2)
+ return ((data >> ((reg & 3) << 3)) & 0xffff);
+ else
+ return data;
+}
+
+static void
+phoenix_pciwrite(u_int b, u_int s, u_int f,
+ u_int reg, u_int val, int width)
+{
+ uint32_t cfgaddr = pci_cfg_offset(b, s, f, reg);
+ uint32_t data = 0;
+
+ if ((width == 2) && (reg & 1))
+ return;
+ else if ((width == 4) && (reg & 3))
+ return;
+
+ if (!pci_bus_status)
+ return;
+
+ if (width == 1) {
+ data = pci_cfg_read_32bit(cfgaddr);
+ data = (data & ~(0xff << ((reg & 3) << 3))) |
+ (val << ((reg & 3) << 3));
+ } else if (width == 2) {
+ data = pci_cfg_read_32bit(cfgaddr);
+ data = (data & ~(0xffff << ((reg & 3) << 3))) |
+ (val << ((reg & 3) << 3));
+ } else {
+ data = val;
+ }
+
+ pci_cfg_write_32bit(cfgaddr, data);
+
+ return;
+}
+
+static uint32_t
+pci_cfg_read_32bit(uint32_t addr)
+{
+ uint32_t temp = 0;
+ uint32_t *p = (uint32_t *) ((uint32_t) pci_config_base + (addr & ~3));
+ uint64_t cerr_cpu_log = 0;
+
+ disable_and_clear_cache_error();
+
+ temp = SWAP32(*p);
+
+ /* Read cache err log */
+ cerr_cpu_log = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID);
+
+ if (cerr_cpu_log) {
+ /* Device don't exist. */
+ temp = ~0x0;
+ }
+ clear_and_enable_cache_error();
+ return temp;
+}
+
+
+static void
+pci_cfg_write_32bit(uint32_t addr, uint32_t data)
+{
+ unsigned int *p = (unsigned int *)((uint32_t) pci_config_base + (addr & ~3));
+
+ *p = SWAP32(data);
+}
+
+static u_int32_t
+xlr_pcib_read_config(device_t dev, u_int b, u_int s, u_int f,
+ u_int reg, int width)
+{
+ return phoenix_pciread(b, s, f, reg, width);
+}
+
+static void
+xlr_pcib_write_config(device_t dev, u_int b, u_int s, u_int f,
+ u_int reg, u_int32_t val, int width)
+{
+ phoenix_pciwrite(b, s, f, reg, val, width);
+}
+
+static int
+xlr_pcib_attach(device_t dev)
+{
+ device_add_child(dev, "pci", 0);
+ bus_generic_attach(dev);
+ return 0;
+}
+
+#define PCIE_LINK_STATE 0x4000
+
+static void
+xlr_pcib_identify(driver_t * driver, device_t parent)
+{
+ xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET);
+ xlr_reg_t reg_link0 = xlr_read_reg(pcie_mmio_le, (0x80 >> 2));
+ xlr_reg_t reg_link1 = xlr_read_reg(pcie_mmio_le, (0x84 >> 2));
+
+ if ((uint16_t) reg_link0 & PCIE_LINK_STATE) {
+ device_printf(parent, "Link 0 up\n");
+ }
+ if ((uint16_t) reg_link1 & PCIE_LINK_STATE) {
+ device_printf(parent, "Link 1 up\n");
+ }
+ BUS_ADD_CHILD(parent, 0, "pcib", 0);
+
+}
+static int
+ xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs);
+static int
+ xlr_release_msi(device_t pcib, device_t dev, int count, int *irqs);
+
+static int
+xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs)
+{
+ int pciirq;
+ int i;
+ device_t parent, tmp;
+
+
+ /* find the lane on which the slot is connected to */
+ tmp = dev;
+ while (1) {
+ parent = device_get_parent(tmp);
+ if (parent == NULL || parent == pcib) {
+ device_printf(dev, "Cannot find parent bus\n");
+ return ENXIO;
+ }
+ if (strcmp(device_get_nameunit(parent), "pci0") == 0)
+ break;
+ tmp = parent;
+ }
+
+ switch (pci_get_slot(tmp)) {
+ case 0:
+ pciirq = PIC_PCIE_LINK0_IRQ;
+ break;
+ case 1:
+ pciirq = PIC_PCIE_LINK1_IRQ;
+ break;
+ case 2:
+ pciirq = PIC_PCIE_LINK2_IRQ;
+ break;
+ case 3:
+ pciirq = PIC_PCIE_LINK3_IRQ;
+ break;
+ default:
+ return ENXIO;
+ }
+
+ irqs[0] = pciirq;
+ /*
+ * For now put in some fixed values for the other requested MSI,
+ * TODO handle multiple messages
+ */
+ for (i = 1; i < count; i++)
+ irqs[i] = pciirq + 64 * i;
+
+ return 0;
+}
+
+static int
+xlr_release_msi(device_t pcib, device_t dev, int count, int *irqs)
+{
+ device_printf(dev, "%s: msi release %d\n", device_get_nameunit(pcib), count);
+ return 0;
+}
+static int
+ xlr_map_msi(device_t pcib, device_t dev, int irq, uint64_t * addr, uint32_t * data);
+
+static int
+xlr_map_msi(device_t pcib, device_t dev, int irq, uint64_t * addr, uint32_t * data)
+{
+ switch (irq) {
+ case PIC_PCIE_LINK0_IRQ:
+ case PIC_PCIE_LINK1_IRQ:
+ case PIC_PCIE_LINK2_IRQ:
+ case PIC_PCIE_LINK3_IRQ:
+ *addr = MIPS_MSI_ADDR(0);
+ *data = MIPS_MSI_DATA(irq);
+ return 0;
+
+ default:
+ device_printf(dev, "%s: map_msi for irq %d - ignored", device_get_nameunit(pcib),
+ irq);
+ return (ENXIO);
+ }
+
+}
+
+static device_method_t xlr_pcib_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_identify, xlr_pcib_identify),
+ DEVMETHOD(device_probe, xlr_pcib_probe),
+ DEVMETHOD(device_attach, xlr_pcib_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_read_ivar, xlr_pcib_read_ivar),
+ DEVMETHOD(bus_alloc_resource, xlr_pci_alloc_resource),
+ DEVMETHOD(bus_release_resource, pci_release_resource),
+ DEVMETHOD(bus_activate_resource, pci_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, mips_platform_pci_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ /* pcib interface */
+ DEVMETHOD(pcib_maxslots, xlr_pcib_maxslots),
+ DEVMETHOD(pcib_read_config, xlr_pcib_read_config),
+ DEVMETHOD(pcib_write_config, xlr_pcib_write_config),
+
+ DEVMETHOD(pcib_route_interrupt, mips_pci_route_interrupt),
+
+ DEVMETHOD(pcib_alloc_msi, xlr_alloc_msi),
+ DEVMETHOD(pcib_release_msi, xlr_release_msi),
+ DEVMETHOD(pcib_map_msi, xlr_map_msi),
+
+ {0, 0}
+};
+
+static driver_t xlr_pcib_driver = {
+ "pcib",
+ xlr_pcib_methods,
+ sizeof(struct xlr_hose_softc),
+};
+
+DRIVER_MODULE(pcib, nexus, xlr_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/mips/rmi/xlrconfig.h b/sys/mips/rmi/xlrconfig.h
new file mode 100644
index 0000000..3ba96eb
--- /dev/null
+++ b/sys/mips/rmi/xlrconfig.h
@@ -0,0 +1,336 @@
+/*-
+ * Copyright (c) 2003-2009 RMI Corporation
+ * 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 RMI Corporation, nor the names of its contributors,
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RMI_BSD */
+#ifndef XLRCONFIG_H
+#define XLRCONFIG_H
+
+#include <sys/types.h>
+#include <mips/rmi/shared_structs.h>
+#include <mips/rmi/shared_structs_func.h>
+
+#define read_c0_register32(reg, sel) \
+({ unsigned int __rv; \
+ __asm__ __volatile__( \
+ ".set\tpush\n\t" \
+ ".set mips32\n\t" \
+ "mfc0\t%0,$%1,%2\n\t" \
+ ".set\tpop" \
+ : "=r" (__rv) : "i" (reg), "i" (sel) ); \
+ __rv;})
+
+#define write_c0_register32(reg, sel, value) \
+ __asm__ __volatile__( \
+ ".set\tpush\n\t" \
+ ".set mips32\n\t" \
+ "mtc0\t%0,$%1,%2\n\t" \
+ ".set\tpop" \
+ : : "r" (value), "i" (reg), "i" (sel) );
+
+#define read_c0_register64(reg, sel) \
+ ({ unsigned int __high, __low; \
+ __asm__ __volatile__( \
+ ".set\tpush\n\t" \
+ ".set mips64\n\t" \
+ "dmfc0\t $8, $%2, %3\n\t" \
+ "dsrl32\t%0, $8, 0\n\t" \
+ "dsll32\t$8, $8, 0\n\t" \
+ "dsrl32\t%1, $8, 0\n\t" \
+ ".set\tpop" \
+ : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\
+ (((unsigned long long)__high << 32) | __low);})
+
+#define write_c0_register64(reg, sel, value) \
+ do{ \
+ unsigned int __high = val>>32; \
+ unsigned int __low = val & 0xffffffff; \
+ __asm__ __volatile__( \
+ ".set\tpush\n\t" \
+ ".set mips64\n\t" \
+ "dsll32\t$8, %1, 0\n\t" \
+ "dsll32\t$9, %0, 0\n\t" \
+ "or\t $8, $8, $9\n\t" \
+ "dmtc0\t $8, $%2, %3\n\t" \
+ ".set\tpop" \
+ :: "r"(high), "r"(low), "i"(reg), "i"(sel):"$8", "$9");\
+ } while(0)
+
+#define read_c2_register32(reg, sel) \
+({ unsigned int __rv; \
+ __asm__ __volatile__( \
+ ".set\tpush\n\t" \
+ ".set mips32\n\t" \
+ "mfc2\t%0,$%1,%2\n\t" \
+ ".set\tpop" \
+ : "=r" (__rv) : "i" (reg), "i" (sel) ); \
+ __rv;})
+
+#define write_c2_register32(reg, sel, value) \
+ __asm__ __volatile__( \
+ ".set\tpush\n\t" \
+ ".set mips32\n\t" \
+ "mtc2\t%0,$%1,%2\n\t" \
+ ".set\tpop" \
+ : : "r" (value), "i" (reg), "i" (sel) );
+
+#define read_c2_register64(reg, sel) \
+ ({ unsigned int __high, __low; \
+ __asm__ __volatile__( \
+ ".set mips64\n\t" \
+ "dmfc2\t $8, $%2, %3\n\t" \
+ "dsrl32\t%0, $8, 0\n\t" \
+ "dsll32\t$8, $8, 0\n\t" \
+ "dsrl32\t%1, $8, 0\n\t" \
+ ".set\tmips0" \
+ : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\
+ (((unsigned long long)__high << 32) | __low);})
+
+#define write_c2_register64(reg, sel, value) \
+ do{ \
+ unsigned int __high = value>>32; \
+ unsigned int __low = value & 0xffffffff; \
+ __asm__ __volatile__( \
+ ".set mips64\n\t" \
+ "dsll32\t$8, %1, 0\n\t" \
+ "dsll32\t$9, %0, 0\n\t" \
+ "dsrl32\t$8, $8, 0\n\t" \
+ "or\t $8, $8, $9\n\t" \
+ "dmtc2\t $8, $%2, %3\n\t" \
+ ".set\tmips0" \
+ :: "r"(__high), "r"(__low), \
+ "i"(reg), "i"(sel) \
+ :"$8", "$9"); \
+ } while(0)
+
+#if 0
+#define xlr_processor_id() \
+({int __id; \
+ __asm__ __volatile__ ( \
+ ".set push\n" \
+ ".set noreorder\n" \
+ ".word 0x40088007\n" \
+ "srl $8, $8, 10\n" \
+ "andi %0, $8, 0x3f\n" \
+ ".set pop\n" \
+ : "=r" (__id) : : "$8"); \
+ __id;})
+#endif
+
+#define xlr_cpu_id() \
+({int __id; \
+ __asm__ __volatile__ ( \
+ ".set push\n" \
+ ".set noreorder\n" \
+ ".word 0x40088007\n" \
+ "srl $8, $8, 4\n" \
+ "andi %0, $8, 0x7\n" \
+ ".set pop\n" \
+ : "=r" (__id) : : "$8"); \
+ __id;})
+
+#define xlr_thr_id() \
+({int __id; \
+ __asm__ __volatile__ ( \
+ ".set push\n" \
+ ".set noreorder\n" \
+ ".word 0x40088007\n" \
+ "andi %0, $8, 0x03\n" \
+ ".set pop\n" \
+ : "=r" (__id) : : "$8"); \
+ __id;})
+
+
+/* Additional registers on the XLR */
+#define MIPS_COP_0_OSSCRATCH 22
+
+#define XLR_CACHELINE_SIZE 32
+
+#define XLR_MAX_CORES 8
+
+/* functions to write to and read from the extended
+ * cp0 registers.
+ * EIRR : Extended Interrupt Request Register
+ * cp0 register 9 sel 6
+ * bits 0...7 are same as cause register 8...15
+ * EIMR : Extended Interrupt Mask Register
+ * cp0 register 9 sel 7
+ * bits 0...7 are same as status register 8...15
+ */
+
+static inline uint64_t
+read_c0_eirr64(void)
+{
+ __uint32_t high, low;
+
+ __asm__ __volatile__(
+ ".set push\n"
+ ".set noreorder\n"
+ ".set noat\n"
+ ".set mips4\n"
+
+ ".word 0x40214806 \n\t"
+ "nop \n\t"
+ "dsra32 %0, $1, 0 \n\t"
+ "sll %1, $1, 0 \n\t"
+
+ ".set pop\n"
+
+ : "=r"(high), "=r"(low)
+ );
+
+ return (((__uint64_t) high) << 32) | low;
+}
+
+static inline __uint64_t
+read_c0_eimr64(void)
+{
+ __uint32_t high, low;
+
+ __asm__ __volatile__(
+ ".set push\n"
+ ".set noreorder\n"
+ ".set noat\n"
+ ".set mips4\n"
+
+ ".word 0x40214807 \n\t"
+ "nop \n\t"
+ "dsra32 %0, $1, 0 \n\t"
+ "sll %1, $1, 0 \n\t"
+
+ ".set pop\n"
+
+ : "=r"(high), "=r"(low)
+ );
+
+ return (((__uint64_t) high) << 32) | low;
+}
+
+static inline void
+write_c0_eirr64(__uint64_t value)
+{
+ __uint32_t low, high;
+
+ high = value >> 32;
+ low = value & 0xffffffff;
+
+ __asm__ __volatile__(
+ ".set push\n"
+ ".set noreorder\n"
+ ".set noat\n"
+ ".set mips4\n\t"
+
+ "dsll32 $2, %1, 0 \n\t"
+ "dsll32 $1, %0, 0 \n\t"
+ "dsrl32 $2, $2, 0 \n\t"
+ "or $1, $1, $2 \n\t"
+ ".word 0x40a14806 \n\t"
+ "nop \n\t"
+
+ ".set pop\n"
+
+ :
+ : "r"(high), "r"(low)
+ : "$1", "$2");
+}
+
+static inline void
+write_c0_eimr64(__uint64_t value)
+{
+ __uint32_t low, high;
+
+ high = value >> 32;
+ low = value & 0xffffffff;
+
+ __asm__ __volatile__(
+ ".set push\n"
+ ".set noreorder\n"
+ ".set noat\n"
+ ".set mips4\n\t"
+
+ "dsll32 $2, %1, 0 \n\t"
+ "dsll32 $1, %0, 0 \n\t"
+ "dsrl32 $2, $2, 0 \n\t"
+ "or $1, $1, $2 \n\t"
+ ".word 0x40a14807 \n\t"
+ "nop \n\t"
+
+ ".set pop\n"
+
+ :
+ : "r"(high), "r"(low)
+ : "$1", "$2");
+}
+
+static __inline__ int
+xlr_test_and_set(int *lock)
+{
+ int oldval = 0;
+
+ __asm__ __volatile__(".set push\n"
+ ".set noreorder\n"
+ "move $9, %2\n"
+ "li $8, 1\n"
+ // "swapw $8, $9\n"
+ ".word 0x71280014\n"
+ "move %1, $8\n"
+ ".set pop\n"
+ : "+m"(*lock), "=r"(oldval)
+ : "r"((unsigned long)lock)
+ : "$8", "$9"
+ );
+
+ return (oldval == 0 ? 1 /* success */ : 0 /* failure */ );
+}
+
+static __inline__ uint32_t
+xlr_mfcr(uint32_t reg)
+{
+ uint32_t val;
+
+ __asm__ __volatile__(
+ "move $8, %1\n"
+ ".word 0x71090018\n"
+ "move %0, $9\n"
+ : "=r"(val)
+ : "r"(reg):"$8", "$9");
+
+ return val;
+}
+
+static __inline__ void
+xlr_mtcr(uint32_t reg, uint32_t val)
+{
+ __asm__ __volatile__(
+ "move $8, %1\n"
+ "move $9, %0\n"
+ ".word 0x71090019\n"
+ :: "r"(val), "r"(reg)
+ : "$8", "$9");
+}
+
+#endif
diff --git a/sys/mips/rmi/xls_ehci.c b/sys/mips/rmi/xls_ehci.c
new file mode 100644
index 0000000..a270507
--- /dev/null
+++ b/sys/mips/rmi/xls_ehci.c
@@ -0,0 +1,303 @@
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (augustss@carlstedt.se) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.18.2.4 2008/04/23 18:54:51 jhb Exp $");
+
+/*
+ * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
+ *
+ * The EHCI 1.0 spec can be found at
+ * http://developer.intel.com/technology/usb/download/ehci-r10.pdf
+ * and the USB 2.0 spec at
+ * http://www.usb.org/developers/docs/usb_20.zip
+ */
+
+/* The low level controller code for EHCI has been split into
+ * PCI probes and EHCI specific code. This was done to facilitate the
+ * sharing of code between *BSD's
+ */
+
+#include "opt_bus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/queue.h>
+#include <sys/lock.h>
+#include <sys/lockmgr.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+/*#include <dev/usb/usbdivar.h> */
+/*#include <dev/usb/usb_mem.h> */
+
+#include <mips/rmi/ehcireg.h>
+#include <mips/rmi/ehcivar.h>
+
+#ifdef USB_DEBUG
+#define EHCI_DEBUG USB_DEBUG
+#define DPRINTF(x) do { if (ehcidebug) logprintf x; } while (0)
+extern int ehcidebug;
+
+#else
+#define DPRINTF(x)
+#endif
+
+static int ehci_xls_attach(device_t self);
+static int ehci_xls_detach(device_t self);
+static int ehci_xls_shutdown(device_t self);
+static int ehci_xls_suspend(device_t self);
+static int ehci_xls_resume(device_t self);
+static void ehci_xls_givecontroller(device_t self);
+static void ehci_xls_takecontroller(device_t self);
+
+static int
+ehci_xls_suspend(device_t self)
+{
+ ehci_softc_t *sc = device_get_softc(self);
+ int err;
+
+ err = bus_generic_suspend(self);
+ if (err)
+ return (err);
+ ehci_power(PWR_SUSPEND, sc);
+
+ return 0;
+}
+
+static int
+ehci_xls_resume(device_t self)
+{
+ ehci_softc_t *sc = device_get_softc(self);
+
+ ehci_xls_takecontroller(self);
+ ehci_power(PWR_RESUME, sc);
+ bus_generic_resume(self);
+
+ return 0;
+}
+
+static int
+ehci_xls_shutdown(device_t self)
+{
+ ehci_softc_t *sc = device_get_softc(self);
+ int err;
+
+ err = bus_generic_shutdown(self);
+ if (err)
+ return (err);
+ ehci_shutdown(sc);
+ ehci_xls_givecontroller(self);
+
+ return 0;
+}
+
+
+static const char *xlr_usb_dev_desc = "RMI XLR USB 2.0 controller";
+static const char *xlr_vendor_desc = "RMI Corp";
+static int
+ehci_xls_probe(device_t self)
+{
+
+ /* TODO see if usb is enabled on the board */
+ device_set_desc(self, xlr_usb_dev_desc);
+ return BUS_PROBE_DEFAULT;
+}
+
+static int
+ehci_xls_attach(device_t self)
+{
+ ehci_softc_t *sc = device_get_softc(self);
+ device_t parent;
+ device_t *neighbors;
+ int err;
+ int rid;
+ int count;
+ int res;
+
+
+ sc->sc_bus.usbrev = USBREV_2_0;
+
+ rid = 0;
+ sc->io_res = bus_alloc_resource(self, SYS_RES_MEMORY, &rid,
+ 0ul, ~0ul, 0x400, RF_ACTIVE);
+ if (!sc->io_res) {
+ device_printf(self, "Could not map memory\n");
+ return ENXIO;
+ }
+ sc->iot = rman_get_bustag(sc->io_res);
+ sc->ioh = rman_get_bushandle(sc->io_res);
+
+ rid = 0;
+ sc->irq_res = bus_alloc_resource(self, SYS_RES_IRQ, &rid,
+ 39, 39, 1, RF_SHAREABLE | RF_ACTIVE);
+ if (sc->irq_res == NULL) {
+ device_printf(self, "Could not allocate irq\n");
+ ehci_xls_detach(self);
+ return ENXIO;
+ }
+ sc->sc_bus.bdev = device_add_child(self, "usb", -1);
+ if (!sc->sc_bus.bdev) {
+ device_printf(self, "Could not add USB device\n");
+ ehci_xls_detach(self);
+ return ENOMEM;
+ }
+ device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+
+ /* ehci_pci_match will never return NULL if ehci_pci_probe succeeded */
+ device_set_desc(sc->sc_bus.bdev, xlr_usb_dev_desc);
+ sprintf(sc->sc_vendor, xlr_vendor_desc);
+
+ err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
+ (driver_intr_t *) ehci_intr, sc, &sc->ih);
+ if (err) {
+ device_printf(self, "Could not setup irq, %d\n", err);
+ sc->ih = NULL;
+ ehci_xls_detach(self);
+ return ENXIO;
+ }
+ /*
+ * Find companion controllers. According to the spec they always
+ * have lower function numbers so they should be enumerated already.
+ */
+ parent = device_get_parent(self);
+ res = device_get_children(parent, &neighbors, &count);
+ if (res != 0) {
+ device_printf(self, "Error finding companion busses\n");
+ ehci_xls_detach(self);
+ return ENXIO;
+ }
+ sc->sc_ncomp = 0;
+
+ ehci_xls_takecontroller(self);
+ err = ehci_init(sc);
+ if (!err) {
+ sc->sc_flags |= EHCI_SCFLG_DONEINIT;
+ err = device_probe_and_attach(sc->sc_bus.bdev);
+ }
+ if (err) {
+ device_printf(self, "USB init failed err=%d\n", err);
+ ehci_xls_detach(self);
+ return EIO;
+ }
+ return 0;
+}
+
+static int
+ehci_xls_detach(device_t self)
+{
+ ehci_softc_t *sc = device_get_softc(self);
+
+ if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
+ ehci_detach(sc, 0);
+ sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
+ }
+ /*
+ * disable interrupts that might have been switched on in ehci_init
+ */
+ if (sc->iot && sc->ioh)
+ bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0);
+
+ if (sc->irq_res && sc->ih) {
+ int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
+
+ if (err)
+ /* XXX or should we panic? */
+ device_printf(self, "Could not tear down irq, %d\n",
+ err);
+ sc->ih = NULL;
+ }
+ if (sc->sc_bus.bdev) {
+ device_delete_child(self, sc->sc_bus.bdev);
+ sc->sc_bus.bdev = NULL;
+ }
+ if (sc->irq_res) {
+ bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
+ sc->irq_res = NULL;
+ }
+ if (sc->io_res) {
+ bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM, sc->io_res);
+ sc->io_res = NULL;
+ sc->iot = 0;
+ sc->ioh = 0;
+ }
+ return 0;
+}
+
+static void
+ehci_xls_takecontroller(device_t self)
+{
+ //device_printf(self, "In func %s\n", __func__);
+}
+
+static void
+ehci_xls_givecontroller(device_t self)
+{
+ //device_printf(self, "In func %s\n", __func__);
+}
+
+static device_method_t ehci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ehci_xls_probe),
+ DEVMETHOD(device_attach, ehci_xls_attach),
+ DEVMETHOD(device_detach, ehci_xls_detach),
+ DEVMETHOD(device_suspend, ehci_xls_suspend),
+ DEVMETHOD(device_resume, ehci_xls_resume),
+ DEVMETHOD(device_shutdown, ehci_xls_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+
+ {0, 0}
+};
+
+static driver_t ehci_driver = {
+ "ehci",
+ ehci_methods,
+ sizeof(ehci_softc_t),
+};
+
+static devclass_t ehci_devclass;
+
+DRIVER_MODULE(ehci, iodi, ehci_driver, ehci_devclass, 0, 0);
+/* DRIVER_MODULE(ehci, cardbus, ehci_driver, ehci_devclass, 0, 0); */
OpenPOWER on IntegriCloud