summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/mips/rmi/Makefile.msgring14
-rw-r--r--sys/mips/rmi/board.c178
-rw-r--r--sys/mips/rmi/board.h275
-rw-r--r--sys/mips/rmi/clock.c213
-rw-r--r--sys/mips/rmi/clock.h40
-rwxr-xr-xsys/mips/rmi/debug.h103
-rw-r--r--sys/mips/rmi/interrupt.h43
-rw-r--r--sys/mips/rmi/iodi.c272
-rw-r--r--sys/mips/rmi/iomap.h110
-rw-r--r--sys/mips/rmi/msgring.c318
-rw-r--r--sys/mips/rmi/msgring.cfg1182
-rwxr-xr-xsys/mips/rmi/msgring.h507
-rw-r--r--sys/mips/rmi/msgring_xls.c218
-rwxr-xr-xsys/mips/rmi/msgring_xls.cfg563
-rw-r--r--sys/mips/rmi/on_chip.c313
-rw-r--r--sys/mips/rmi/pcibus.c328
-rw-r--r--sys/mips/rmi/pcibus.h49
-rw-r--r--sys/mips/rmi/perfmon.h168
-rw-r--r--sys/mips/rmi/perfmon_kern.c162
-rw-r--r--sys/mips/rmi/perfmon_percpu.c299
-rw-r--r--sys/mips/rmi/perfmon_utils.h113
-rw-r--r--sys/mips/rmi/perfmon_xlrconfig.h156
-rw-r--r--sys/mips/rmi/pic.h257
-rwxr-xr-xsys/mips/rmi/shared_structs.h108
-rwxr-xr-xsys/mips/rmi/shared_structs_func.h54
-rwxr-xr-xsys/mips/rmi/shared_structs_offsets.h76
-rw-r--r--sys/mips/rmi/uart_bus_xlr_iodi.c73
-rw-r--r--sys/mips/rmi/uart_cpu_mips_xlr.c171
-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.c442
-rw-r--r--sys/mips/rmi/xlr_machdep.c650
-rw-r--r--sys/mips/rmi/xlr_pci.c410
-rw-r--r--sys/mips/rmi/xlrconfig.h327
-rw-r--r--sys/mips/rmi/xls_ehci.c305
35 files changed, 8827 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..44a8015
--- /dev/null
+++ b/sys/mips/rmi/board.c
@@ -0,0 +1,178 @@
+/*********************************************************************
+ *
+ * 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/xlr/msgring.h>
+#include <mips/xlr/board.h>
+#include <mips/xlr/pic.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..b296d14
--- /dev/null
+++ b/sys/mips/rmi/board.h
@@ -0,0 +1,275 @@
+/*-
+ * 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/clock.c b/sys/mips/rmi/clock.c
new file mode 100644
index 0000000..44ba886
--- /dev/null
+++ b/sys/mips/rmi/clock.c
@@ -0,0 +1,213 @@
+/*-
+ * 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/xlr/iomap.h>
+#include <mips/xlr/clock.h>
+#include <mips/xlr/interrupt.h>
+#include <mips/xlr/pic.h>
+#include <mips/xlr/shared_structs.h>
+
+#ifdef XLR_PERFMON
+#include <mips/xlr/perfmon.h>
+#endif
+
+int hw_clockrate;
+SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD, &hw_clockrate,
+ 0, "CPU instruction clock rate");
+
+#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;
+}
+
+/*
+* count_compare_clockhandler:
+*
+* Handle the clock interrupt when count becomes equal to
+* compare.
+*/
+void
+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_process((struct clockframe *)tf);
+ if (count_scale_factor[cpu] == STAT_PROF_CLOCK_SCALE_FACTOR) {
+ statclock((struct clockframe *)tf);
+ if(profprocs != 0) {
+ profclock((struct clockframe *)tf);
+ }
+ count_scale_factor[cpu] = 0;
+ }
+
+ /* If needed , handle count compare tick skew here */
+ }
+
+ critical_exit();
+}
+
+void
+pic_hardclockhandler(struct trapframe *tf)
+{
+ int cpu = PCPU_GET(cpuid);
+
+ critical_enter();
+
+ if (cpu == 0) {
+ scale_factor++;
+ hardclock((struct clockframe *)tf);
+ if (scale_factor == STAT_PROF_CLOCK_SCALE_FACTOR) {
+ statclock((struct clockframe *)tf);
+ if(profprocs != 0) {
+ profclock((struct clockframe *)tf);
+ }
+ 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();
+}
+
+void
+pic_timecounthandler(struct trapframe *tf)
+{
+}
+
+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_intr("compare", IRQ_TIMER,
+ (driver_intr_t *)count_compare_clockhandler,
+ NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL);
+
+ /* timekeeping timer interrupt for cpu 0 */
+ cpu_establish_intr("hardclk", PIC_TIMER_7_IRQ,
+ (driver_intr_t *)pic_hardclockhandler,
+ NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL);
+
+ /* this is used by timecounter */
+ cpu_establish_intr("timecount", PIC_TIMER_6_IRQ,
+ (driver_intr_t *)pic_timecounthandler,
+ NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL);
+
+ 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 */
+
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff));
+ xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff);
+ xlr_write_reg(mmio, PIC_IRT_0_TIMER_7, (1 << cpu));
+ 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));
+ mtx_unlock_spin(&xlr_pic_lock);
+ } else {
+ /* Setup count-compare interrupt for vcpu[1-31] */
+ mips_wr_compare((xlr_boot1_info.cpu_frequency)/hz);
+ }
+}
+
+
+
+unsigned __attribute__((no_instrument_function))
+platform_get_timecount(struct timecounter *tc)
+{
+ xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
+
+ return 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0);
+}
diff --git a/sys/mips/rmi/clock.h b/sys/mips/rmi/clock.h
new file mode 100644
index 0000000..c582de5
--- /dev/null
+++ b/sys/mips/rmi/clock.h
@@ -0,0 +1,40 @@
+/*-
+ * 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)
+
+void count_compare_clockhandler(struct trapframe *);
+void pic_hardclockhandler(struct trapframe *);
+void pic_timecounthandler(struct trapframe *);
+
+#endif /* _RMI_CLOCK_H_ */
diff --git a/sys/mips/rmi/debug.h b/sys/mips/rmi/debug.h
new file mode 100755
index 0000000..2507a04
--- /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/interrupt.h b/sys/mips/rmi/interrupt.h
new file mode 100644
index 0000000..c13a27c
--- /dev/null
+++ b/sys/mips/rmi/interrupt.h
@@ -0,0 +1,43 @@
+/*-
+ * 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/iodi.c b/sys/mips/rmi/iodi.c
new file mode 100644
index 0000000..3a8d3bd
--- /dev/null
+++ b/sys/mips/rmi/iodi.c
@@ -0,0 +1,272 @@
+/*-
+ * 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/xlr/iomap.h>
+#include <mips/xlr/pic.h>
+#include <mips/xlr/board.h>
+#include <sys/rman.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_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_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? */
+ 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)));
+ mtx_unlock_spin(&xlr_pic_lock);
+
+ cpu_establish_intr("uart", PIC_UART_0_IRQ,
+ (driver_intr_t *)intr, (void *)arg, flags, cookiep,
+ NULL, NULL);
+
+ } else if (strcmp(device_get_name(child),"rge") == 0) {
+ mtx_lock_spin(&xlr_pic_lock);
+ reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + ires->r_flags - PIC_IRQ_BASE);
+ xlr_write_reg(mmio, PIC_IRT_1_BASE + ires->r_flags - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31));
+ mtx_unlock_spin(&xlr_pic_lock);
+ cpu_establish_intr("rge", ires->r_flags,
+ (driver_intr_t *)intr, (void *)arg,
+ flags, cookiep, NULL, NULL);
+ } else if (strcmp(device_get_name(child),"ehci") == 0) {
+ 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));
+ mtx_unlock_spin(&xlr_pic_lock);
+ cpu_establish_intr("ehci", PIC_USB_IRQ,
+ (driver_intr_t *)intr, (void *)arg,
+ flags, cookiep, (flags & INTR_FAST)? NULL: pic_usb_ack , NULL);
+ }
+
+ BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, intr, arg,
+ cookiep);
+ return (0);
+}
+
+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 = 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..4aa8f70
--- /dev/null
+++ b/sys/mips/rmi/iomap.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 _RMI_IOMAP_H_
+#define _RMI_IOMAP_H_
+
+#include <machine/endian.h>
+
+#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_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..472ad43
--- /dev/null
+++ b/sys/mips/rmi/msgring.c
@@ -0,0 +1,318 @@
+/*-
+ * 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/xlr/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..fba504d
--- /dev/null
+++ b/sys/mips/rmi/msgring.h
@@ -0,0 +1,507 @@
+/*-
+ * 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/xlr/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 { \
+ mtx_lock_spin(lock); \
+ msgrng_flags_save(mflags); \
+ }while(0)
+
+#define msgrng_access_restore(lock, mflags) do { \
+ msgrng_flags_restore(mflags); \
+ 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..f1b116e
--- /dev/null
+++ b/sys/mips/rmi/msgring_xls.c
@@ -0,0 +1,218 @@
+/**********************************************************
+ * -----------------DO NOT EDIT THIS FILE------------------
+ * This file has been autogenerated by the build process
+ * from "msgring_xls.cfg"
+ **********************************************************/
+
+#include <mips/xlr/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..8addfc4
--- /dev/null
+++ b/sys/mips/rmi/on_chip.c
@@ -0,0 +1,313 @@
+/*-
+ * 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/xlr/interrupt.h>
+#include <mips/xlr/msgring.h>
+#include <mips/xlr/iomap.h>
+#include <mips/xlr/debug.h>
+#include <mips/xlr/pic.h>
+#include <mips/xlr/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);
+
+ mtx_lock_spin(&msgrng_lock);
+ tx_stn_handlers[major].action = action;
+ tx_stn_handlers[major].dev_id = dev_id;
+ mtx_unlock_spin(&msgrng_lock);
+
+ if (xlr_test_and_set(&msgring_int_enabled)) {
+ platform_prep_smp_launch();
+
+ cpu_establish_intr("msgring", IRQ_MSGRING,
+ (driver_intr_t *)msgring_process_fast_intr,
+ NULL, INTR_TYPE_NET|INTR_FAST, &cookie, NULL, NULL);
+
+ /* 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));
+ }
+}
+
+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..0aeacd6
--- /dev/null
+++ b/sys/mips/rmi/pcibus.c
@@ -0,0 +1,328 @@
+/*-
+ * 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/xlr/iomap.h>
+#include <mips/xlr/pic.h>
+#include <mips/xlr/shared_structs.h>
+#include <mips/xlr/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/pci/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_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 (irq->r_start != irq->r_end) {
+ device_printf(dev, "Interrupt allocation %lu != %lu\n",
+ irq->r_start, irq->r_end);
+ return EINVAL;
+ }
+
+ xlrirq = irq->r_start;
+ if (strcmp(device_get_name(dev),"pcib") != 0)
+ return 0;
+
+ if (xlr_board_info.is_xls == 0) {
+ 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)));
+ mtx_unlock_spin(&xlr_pic_lock);
+ cpu_establish_intr(device_get_name(child), PIC_PCIX_IRQ,
+ (driver_intr_t *)intr, (void *)arg, flags, cookiep,
+ pic_pcix_ack, bridge_pcix_ack);
+ } else {
+ 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));
+ mtx_unlock_spin(&xlr_pic_lock);
+
+ if (flags & INTR_FAST)
+ cpu_establish_intr(device_get_name(child), xlrirq,
+ (driver_intr_t *)intr, (void *)arg, flags, cookiep,
+ NULL, bridge_pcie_ack);
+ else
+ cpu_establish_intr(device_get_name(child), xlrirq,
+ (driver_intr_t *)intr, (void *)arg, flags, cookiep,
+ pic_pcie_ack, bridge_pcie_ack);
+
+ }
+ return bus_generic_setup_intr(dev, child, irq, flags, intr,
+ arg, cookiep);
+}
+
+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");
+}
+
+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_start, 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, 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);
+ }
+ va = pmap_map_uncached(&va_start, start, start + count);
+ rman_set_bushandle(rv, va);
+ /* bushandle is same as virtual addr */
+ rman_set_virtual(rv, (void *)va);
+ rman_set_bustag(rv, MIPS_BUS_SPACE_PCI);
+ }
+
+ if (needactivate) {
+ if (bus_activate_resource(child, type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
+ }
+ }
+
+ return rv;
+}
+
+int
+pci_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_activate_resource(r));
+}
+
+int
+pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_deactivate_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..ed4bb97
--- /dev/null
+++ b/sys/mips/rmi/pcibus.h
@@ -0,0 +1,49 @@
+/*-
+ * 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);
diff --git a/sys/mips/rmi/perfmon.h b/sys/mips/rmi/perfmon.h
new file mode 100644
index 0000000..1ba6c46
--- /dev/null
+++ b/sys/mips/rmi/perfmon.h
@@ -0,0 +1,168 @@
+/*-
+ * 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/xlr/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..1e4b7ce2
--- /dev/null
+++ b/sys/mips/rmi/perfmon_kern.c
@@ -0,0 +1,162 @@
+/*-
+ * 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/xlr/perfmon.h>
+#include <mips/xlr/pic.h>
+#include <sys/mutex.h>
+#include <mips/xlr/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..5980ff7
--- /dev/null
+++ b/sys/mips/rmi/perfmon_percpu.c
@@ -0,0 +1,299 @@
+/*-
+ * 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/xlr/xlrconfig.h>
+#include <mips/xlr/perfmon_xlrconfig.h>
+#include <mips/xlr/perfmon.h>
+#include <mips/xlr/perfmon_utils.h>
+#include <mips/xlr/pic.h>
+#include <mips/xlr/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..7d86184
--- /dev/null
+++ b/sys/mips/rmi/perfmon_utils.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 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..8156c12
--- /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/xlr/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..366a736
--- /dev/null
+++ b/sys/mips/rmi/pic.h
@@ -0,0 +1,257 @@
+/*-
+ * 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_
+
+
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <mips/xlr/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;
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_read_reg(mmio, PIC_CTRL);
+ 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);
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_CTRL, control);
+ 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);
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_CTRL, (control | xlr_read_reg(mmio, PIC_CTRL)));
+ 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)) {
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE) ));
+ 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)) {
+ mtx_lock_spin(&xlr_pic_lock);
+ xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE) ));
+ mtx_unlock_spin(&xlr_pic_lock);
+ return;
+ }
+}
+
+#endif /* _RMI_PIC_H_ */
diff --git a/sys/mips/rmi/shared_structs.h b/sys/mips/rmi/shared_structs.h
new file mode 100755
index 0000000..fb9505f
--- /dev/null
+++ b/sys/mips/rmi/shared_structs.h
@@ -0,0 +1,108 @@
+/*-
+ * 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..5432075
--- /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..6cbabd8
--- /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/uart_bus_xlr_iodi.c b/sys/mips/rmi/uart_bus_xlr_iodi.c
new file mode 100644
index 0000000..20415f4
--- /dev/null
+++ b/sys/mips/rmi/uart_bus_xlr_iodi.c
@@ -0,0 +1,73 @@
+/*-
+ * 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 <dev/uart/uart.h>
+#include <dev/uart/uart_bus.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),
+};
+
+static int
+uart_iodi_probe(device_t dev)
+{
+ struct uart_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->sc_class = &uart_ns8250_class;
+
+ /* 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..09703f5
--- /dev/null
+++ b/sys/mips/rmi/uart_cpu_mips_xlr.c
@@ -0,0 +1,171 @@
+/*-
+ * 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>
+
+static int xlr_uart_probe(struct uart_bas *bas);
+static void xlr_uart_init(struct uart_bas *bas, int, int, int, int);
+static void xlr_uart_term(struct uart_bas *bas);
+static void xlr_uart_putc(struct uart_bas *bas, int);
+static int xlr_uart_poll(struct uart_bas *bas);
+static int xlr_uart_getc(struct uart_bas *bas);
+struct mtx xlr_uart_mtx; /*UartLock*/
+
+struct uart_ops xlr_uart_ns8250_ops = {
+ .probe = xlr_uart_probe,
+ .init = xlr_uart_init,
+ .term = xlr_uart_term,
+ .putc = xlr_uart_putc,
+ .poll = xlr_uart_poll,
+ .getc = xlr_uart_getc,
+};
+
+bus_space_tag_t uart_bus_space_io;
+bus_space_tag_t uart_bus_space_mem;
+
+static __inline void xlr_uart_lock(struct mtx *hwmtx)
+{
+ if(!mtx_initialized(hwmtx))
+ return;
+ if(!kdb_active && hwmtx != NULL)
+ mtx_lock_spin(hwmtx);
+}
+
+static __inline void xlr_uart_unlock(struct mtx *hwmtx)
+{
+ if(!mtx_initialized(hwmtx))
+ return;
+ if(!kdb_active && hwmtx != NULL)
+ mtx_unlock_spin(hwmtx);
+}
+
+
+static int xlr_uart_probe(struct uart_bas *bas)
+{
+ int res;
+ xlr_uart_lock(&xlr_uart_mtx);
+ res = uart_ns8250_ops.probe(bas);
+ xlr_uart_unlock(&xlr_uart_mtx);
+ return res;
+}
+
+static void xlr_uart_init(struct uart_bas *bas, int baudrate, int databits,
+ int stopbits, int parity)
+
+{
+ xlr_uart_lock(&xlr_uart_mtx);
+ uart_ns8250_ops.init(bas,baudrate,databits,stopbits,parity);
+ xlr_uart_unlock(&xlr_uart_mtx);
+}
+
+static void xlr_uart_term(struct uart_bas *bas)
+{
+ xlr_uart_lock(&xlr_uart_mtx);
+ uart_ns8250_ops.term(bas);
+ xlr_uart_unlock(&xlr_uart_mtx);
+}
+
+static void xlr_uart_putc(struct uart_bas *bas, int c)
+{
+ xlr_uart_lock(&xlr_uart_mtx);
+ uart_ns8250_ops.putc(bas,c);
+ xlr_uart_unlock(&xlr_uart_mtx);
+}
+
+static int xlr_uart_poll(struct uart_bas *bas)
+{
+ int res;
+ xlr_uart_lock(&xlr_uart_mtx);
+ res = uart_ns8250_ops.poll(bas);
+ xlr_uart_unlock(&xlr_uart_mtx);
+ return res;
+}
+
+static int xlr_uart_getc(struct uart_bas *bas)
+{
+ return uart_ns8250_ops.getc(bas);
+}
+
+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 = xlr_uart_ns8250_ops;
+ di->bas.chan = 0;
+ di->bas.bst = uart_bus_space_mem;
+ /* TODO Need to call bus_space_map() here */
+ di->bas.bsh = 0xbef14000; /* Try with UART0 */
+ di->bas.regshft = 2;
+ /* divisor = rclk / (baudrate * 16); */
+ di->bas.rclk = 66000000;
+
+ di->baudrate = 38400;
+ di->databits = 8;
+ di->stopbits = 1;
+ di->parity = UART_PARITY_NONE;
+
+ /* TODO: Read env variables for all console parameters */
+
+ return (0);
+}
+
+static void xlr_uart_mtx_init(void *dummy __unused)
+{
+ mtx_init(&xlr_uart_mtx, "uart lock",NULL,MTX_SPIN);
+}
+SYSINIT(xlr_init_uart_mtx, SI_SUB_LOCK, SI_ORDER_ANY, xlr_uart_mtx_init, NULL);
+
diff --git a/sys/mips/rmi/xlr_boot1_console.c b/sys/mips/rmi/xlr_boot1_console.c
new file mode 100644
index 0000000..01e67b5
--- /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/xlr/xlrconfig.h>
+#include <mips/xlr/shared_structs.h>
+#include <mips/xlr/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..60e51c5
--- /dev/null
+++ b/sys/mips/rmi/xlr_i2c.c
@@ -0,0 +1,442 @@
+/*-
+ * 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/xlr/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..f28bdaa
--- /dev/null
+++ b/sys/mips/rmi/xlr_machdep.c
@@ -0,0 +1,650 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD$
+ */
+#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/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 <machine/mips-exts.h>
+
+#include <mips/xlr/iomap.h>
+#include <mips/xlr/clock.h>
+#include <mips/xlr/msgring.h>
+#include <mips/xlr/xlrconfig.h>
+#include <mips/xlr/interrupt.h>
+#include <mips/xlr/pic.h>
+
+#ifdef XLR_PERFMON
+#include <mips/xlr/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;
+
+/*
+ * 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;
+extern uint32_t cpu_ltop_map[MAXCPU];
+extern 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 */
+ platform_update_intrmask(IPI_SMP_CALL_FUNCTION);
+ platform_update_intrmask(IPI_STOP);
+ platform_update_intrmask(IPI_RENDEZVOUS);
+ platform_update_intrmask(IPI_AST);
+ platform_update_intrmask(IRQ_TIMER);
+#ifdef XLR_PERFMON
+ platform_update_intrmask(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;
+void
+platform_start()
+{
+ 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 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 */
+ hw_clockrate = xlr_boot1_info.cpu_frequency/1000000 ;
+ cninit();
+
+ printf("Environment (from %d args):\n", xlr_argc-1);
+ if (xlr_argc == 1)
+ printf("\tNone\n");
+ for(i=1,j=0; i<xlr_argc; i++) {
+ int len = strlen(xlr_argv[i]);
+ if (j + len + 2 > sizeof(boot1_env)) {
+ printf("*** Environment could not be copied in full\n");
+ break;
+ }
+
+ printf("\t%s\n", xlr_argv[i]);
+ memcpy(&boot1_env[j], xlr_argv[i], len+1); /* copy the '\0' too */
+ j += len+1;
+ }
+ boot1_env[j] = '\0';
+ kern_envp = boot1_env;
+
+ 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();
+ pcpup = (struct pcpu *)NULL; /* TODO To be removed */
+
+#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_unmapped_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.
+ */
+ on_chip_init();
+ tick_init();
+}
+
+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
+ */
+ mtx_lock_spin(&sched_lock);
+ disable_msgring_int(NULL);
+ it->i_pending = 1;
+ if (TD_AWAITING_INTR(td)) {
+ CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid,
+ p->p_comm);
+ TD_CLR_IWAIT(td);
+ setrunqueue(td, SRQ_INTR);
+ } else {
+ CTR4(KTR_INTR, "%s: pid %d (%s): state %d",
+ __func__, p->p_pid, p->p_comm, td->td_state);
+ }
+ mtx_unlock_spin(&sched_lock);
+
+}
+#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 */
+ mtx_lock_spin(&sched_lock);
+ sched_bind(td, ithd->i_cpu);
+ mtx_unlock_spin(&sched_lock);
+
+// 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(0);
+ }
+ 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);
+ }
+ mtx_lock_spin(&sched_lock);
+ if (!ithd->i_pending && !(ithd->i_flags & MIT_DEAD)) {
+ TD_SET_IWAIT(td);
+ enable_msgring_int(NULL);
+ mi_switch(SW_VOL, NULL);
+ }
+ mtx_unlock_spin(&sched_lock);
+ }
+
+}
+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 = kthread_create(msgring_process, (void *)ithd, &p,
+ RFSTOPPED | RFHIGHPID, 0, "%s", ithd_name[cpu]);
+ if (error)
+ panic("kthread_create() failed with %d", error);
+ td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */
+ mtx_lock_spin(&sched_lock);
+ td->td_ksegrp->kg_pri_class = PRI_ITHD;
+ TD_SET_IWAIT(td);
+ mtx_unlock_spin(&sched_lock);
+ td->td_pflags |= TDP_ITHREAD;
+ 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..31fe5cf
--- /dev/null
+++ b/sys/mips/rmi/xlr_pci.c
@@ -0,0 +1,410 @@
+/*-
+ * 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 <machine/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/xlr/iomap.h>
+#include <mips/xlr/pic.h>
+#include <mips/xlr/shared_structs.h>
+#include <mips/xlr/board.h>
+#include <mips/pci/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, u_long *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..c446595
--- /dev/null
+++ b/sys/mips/rmi/xlrconfig.h
@@ -0,0 +1,327 @@
+/*-
+ * 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/xlr/shared_structs.h>
+#include <mips/xlr/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..7d44eee
--- /dev/null
+++ b/sys/mips/rmi/xls_ehci.c
@@ -0,0 +1,305 @@
+/*-
+ * 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/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 <dev/usb/ehcireg.h>
+#include <dev/usb/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