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