diff --git a/sys/mips/rmi/Makefile.msgring b/sys/mips/rmi/Makefile.msgring new file mode 100644 index 000000000000..d04978e5d1f7 --- /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 000000000000..44a80151ea54 --- /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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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 000000000000..b296d14804ac --- /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 000000000000..44ba886c2f3e --- /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 /* RCS ID & Copyright macro defns */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef XLR_PERFMON +#include +#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 000000000000..c582de529fab --- /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 000000000000..2507a0478de4 --- /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 + +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 000000000000..c13a27c756cb --- /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 000000000000..3a8d3bde6abb --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +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 000000000000..4aa8f70b3a08 --- /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 + +#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 000000000000..472ad43c9e7c --- /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 + +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 000000000000..cf9ea54bfe30 --- /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 000000000000..fba504daa3b2 --- /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 + +#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 000000000000..f1b116e8f6b0 --- /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 + +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 000000000000..35bfb17f4c46 --- /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 000000000000..8addfc4608a6 --- /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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +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 + * 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 +__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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +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 000000000000..ed4bb9768ec7 --- /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 000000000000..1ba6c468e645 --- /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 + +/* + * 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 000000000000..1e4b7ce20505 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +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; inewptr == 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 000000000000..5980ff76389c --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; threadperf_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 000000000000..7d86184ff304 --- /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 /* 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 /* 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 000000000000..366a73659c76 --- /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 +#include +#include + +#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 000000000000..fb9505f0a416 --- /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 000000000000..54320757b1f6 --- /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 000000000000..6cbabd8aa73e --- /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 000000000000..20415f4136d3 --- /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 +__FBSDID("$FreeBSD: src/sys/dev/uart/uart_bus_iodi.c,v 1.6.2.5 2006/02/15 09:16:01 marius Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +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 000000000000..09703f55d4b6 --- /dev/null +++ b/sys/mips/rmi/uart_cpu_mips_xlr.c @@ -0,0 +1,171 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +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 000000000000..01e67b573f33 --- /dev/null +++ b/sys/mips/rmi/xlr_boot1_console.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * 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 +__FBSDID("$FreeBSD$"); + +#include "opt_comconsole.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#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 000000000000..8b51a7f10f1c --- /dev/null +++ b/sys/mips/rmi/xlr_csum_nocopy.S @@ -0,0 +1,217 @@ +#include + + +/* + * 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 000000000000..60e51c596a85 --- /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 +__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 +#include +#include +#include +#include +#include + + +#include +#include + +#include +#include + +#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; ctrmem_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 000000000000..f28bdaa63cbe --- /dev/null +++ b/sys/mips/rmi/xlr_machdep.c @@ -0,0 +1,650 @@ +/*- + * Copyright (c) 2002-2004 Juli Mallett + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* cinit() */ +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef XLR_PERFMON +#include +#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< 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; inum_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; ii_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 000000000000..31fe5cf73062 --- /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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#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 +#include +#include + +#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 000000000000..7d44eee46624 --- /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 +__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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#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); */