1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-01 12:19:28 +00:00

More initial RMI files. Note that these so far do NOT

compile and many of them may disappear. For example
the xlr_boot1_console.c is old code that is ifdef'd out.
I will clean these sorts of things up as I make progress
on the port. So far the only thing I have I think straightened
out is the bits around the interupt handling... and hey that
may be broke ;-)
This commit is contained in:
Randall Stewart 2009-10-15 21:14:42 +00:00
parent 022e93cf87
commit 257c916acf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/mips/; revision=198160
35 changed files with 8827 additions and 0 deletions

View File

@ -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*

178
sys/mips/rmi/board.c Normal file
View File

@ -0,0 +1,178 @@
/*********************************************************************
*
* Copyright 2003-2006 Raza Microelectronics, Inc. (RMI). All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY Raza Microelectronics, Inc. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RMI OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* *****************************RMI_2**********************************/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/cpufunc.h>
#include <mips/xlr/msgring.h>
#include <mips/xlr/board.h>
#include <mips/xlr/pic.h>
static int xlr_rxstn_to_txstn_map[128] = {
[0 ... 7] = TX_STN_CPU_0,
[8 ... 15] = TX_STN_CPU_1,
[16 ... 23] = TX_STN_CPU_2,
[24 ... 31] = TX_STN_CPU_3,
[32 ... 39] = TX_STN_CPU_4,
[40 ... 47] = TX_STN_CPU_5,
[48 ... 55] = TX_STN_CPU_6,
[56 ... 63] = TX_STN_CPU_7,
[64 ... 95] = TX_STN_INVALID,
[96 ... 103] = TX_STN_GMAC,
[104 ... 107] = TX_STN_DMA,
[108 ... 111] = TX_STN_INVALID,
[112 ... 113] = TX_STN_XGS_0,
[114 ... 115] = TX_STN_XGS_1,
[116 ... 119] = TX_STN_INVALID,
[120 ... 127] = TX_STN_SAE
};
static int xls_rxstn_to_txstn_map[128] = {
[0 ... 7] = TX_STN_CPU_0,
[8 ... 15] = TX_STN_CPU_1,
[16 ... 23] = TX_STN_CPU_2,
[24 ... 31] = TX_STN_CPU_3,
[32 ... 63] = TX_STN_INVALID,
[64 ... 71] = TX_STN_PCIE,
[72 ... 79] = TX_STN_INVALID,
[80 ... 87] = TX_STN_GMAC1,
[88 ... 95] = TX_STN_INVALID,
[96 ... 103] = TX_STN_GMAC0,
[104 ... 107] = TX_STN_DMA,
[108 ... 111] = TX_STN_CDE,
[112 ... 119] = TX_STN_INVALID,
[120 ... 127] = TX_STN_SAE
};
struct stn_cc *xlr_core_cc_configs[] = {&cc_table_cpu_0, &cc_table_cpu_1,
&cc_table_cpu_2, &cc_table_cpu_3,
&cc_table_cpu_4, &cc_table_cpu_5,
&cc_table_cpu_6, &cc_table_cpu_7 };
struct stn_cc *xls_core_cc_configs[] = {&xls_cc_table_cpu_0, &xls_cc_table_cpu_1,
&xls_cc_table_cpu_2, &xls_cc_table_cpu_3};
struct xlr_board_info xlr_board_info;
/*
* All our knowledge of chip and board that cannot be detected by probing
* at run-time goes here
*/
int xlr_board_info_setup()
{
if (xlr_is_xls()) {
xlr_board_info.is_xls = 1;
xlr_board_info.nr_cpus = 8;
xlr_board_info.usb = 1;
xlr_board_info.cfi =
(xlr_boot1_info.board_major_version != RMI_XLR_BOARD_ARIZONA_VIII);
xlr_board_info.pci_irq = 0;
xlr_board_info.credit_configs = xls_core_cc_configs;
xlr_board_info.bucket_sizes = &xls_bucket_sizes;
xlr_board_info.msgmap = xls_rxstn_to_txstn_map;
xlr_board_info.gmacports = 8;
/* network block 0 */
xlr_board_info.gmac_block[0].type = XLR_GMAC;
xlr_board_info.gmac_block[0].enabled = 0xf;
xlr_board_info.gmac_block[0].credit_config = &xls_cc_table_gmac0;
xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0;
xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0;
if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI)
xlr_board_info.gmac_block[0].mode = XLR_PORT0_RGMII;
else
xlr_board_info.gmac_block[0].mode = XLR_SGMII;
xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET;
xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ;
xlr_board_info.gmac_block[0].baseinst = 0;
/* network block 1 */
xlr_board_info.gmac_block[1].type = XLR_GMAC;
xlr_board_info.gmac_block[1].enabled = 0xf;
xlr_board_info.gmac_block[1].credit_config = &xls_cc_table_gmac1;
xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_GMAC1_TX0;
xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_GMAC1_FR_0;
xlr_board_info.gmac_block[1].mode = XLR_SGMII;
xlr_board_info.gmac_block[1].baseaddr = XLR_IO_GMAC_4_OFFSET;
xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ;
xlr_board_info.gmac_block[1].baseinst = 4;
/* network block 2 */
xlr_board_info.gmac_block[2].enabled = 0; /* disabled on XLS */
} else {
xlr_board_info.is_xls = 0;
xlr_board_info.nr_cpus = 32;
xlr_board_info.usb = 0;
xlr_board_info.cfi = 1;
xlr_board_info.pci_irq = 0;
xlr_board_info.credit_configs = xlr_core_cc_configs;
xlr_board_info.bucket_sizes = &bucket_sizes;
xlr_board_info.msgmap = xlr_rxstn_to_txstn_map;
xlr_board_info.gmacports = 4;
/* GMAC0 */
xlr_board_info.gmac_block[0].type = XLR_GMAC;
xlr_board_info.gmac_block[0].enabled = 0xf;
xlr_board_info.gmac_block[0].credit_config = &cc_table_gmac;
xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0;
xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0;
xlr_board_info.gmac_block[0].mode = XLR_RGMII;
xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET;
xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ;
xlr_board_info.gmac_block[0].baseinst = 0;
/* XGMAC0 */
xlr_board_info.gmac_block[1].type = XLR_XGMAC;
xlr_board_info.gmac_block[1].enabled = 1;
xlr_board_info.gmac_block[1].credit_config = &cc_table_xgs_0;
xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_XGS0_TX;
xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_XGS0FR;
xlr_board_info.gmac_block[1].mode = -1;
xlr_board_info.gmac_block[1].baseaddr = XLR_IO_XGMAC_0_OFFSET;
xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ;
xlr_board_info.gmac_block[1].baseinst = 4;
/* XGMAC1 */
xlr_board_info.gmac_block[2].type = XLR_XGMAC;
xlr_board_info.gmac_block[2].enabled = 1;
xlr_board_info.gmac_block[2].credit_config = &cc_table_xgs_1;
xlr_board_info.gmac_block[2].station_txbase = MSGRNG_STNID_XGS1_TX;
xlr_board_info.gmac_block[2].station_rfr = MSGRNG_STNID_XGS1FR;
xlr_board_info.gmac_block[2].mode = -1;
xlr_board_info.gmac_block[2].baseaddr = XLR_IO_XGMAC_1_OFFSET;
xlr_board_info.gmac_block[2].baseirq = PIC_XGS_1_IRQ;
xlr_board_info.gmac_block[2].baseinst = 5;
}
return 0;
}

275
sys/mips/rmi/board.h Normal file
View File

@ -0,0 +1,275 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#ifndef _RMI_BOARD_H_
#define _RMI_BOARD_H_
#define RMI_XLR_BOARD_ARIZONA_I 1
#define RMI_XLR_BOARD_ARIZONA_II 2
#define RMI_XLR_BOARD_ARIZONA_III 3
#define RMI_XLR_BOARD_ARIZONA_IV 4
#define RMI_XLR_BOARD_ARIZONA_V 5
#define RMI_XLR_BOARD_ARIZONA_VI 6
#define RMI_XLR_BOARD_ARIZONA_VII 7
#define RMI_XLR_BOARD_ARIZONA_VIII 8
#define RMI_CHIP_XLR308_A0 0x0c0600
#define RMI_CHIP_XLR508_A0 0x0c0700
#define RMI_CHIP_XLR516_A0 0x0c0800
#define RMI_CHIP_XLR532_A0 0x0c0900
#define RMI_CHIP_XLR716_A0 0x0c0a00
#define RMI_CHIP_XLR732_A0 0x0c0b00
#define RMI_CHIP_XLR308_A1 0x0c0601
#define RMI_CHIP_XLR508_A1 0x0c0701
#define RMI_CHIP_XLR516_A1 0x0c0801
#define RMI_CHIP_XLR532_A1 0x0c0901
#define RMI_CHIP_XLR716_A1 0x0c0a01
#define RMI_CHIP_XLR732_A1 0x0c0b01
#define RMI_CHIP_XLR308_B0 0x0c0602
#define RMI_CHIP_XLR508_B0 0x0c0702
#define RMI_CHIP_XLR516_B0 0x0c0802
#define RMI_CHIP_XLR532_B0 0x0c0902
#define RMI_CHIP_XLR716_B0 0x0c0a02
#define RMI_CHIP_XLR732_B0 0x0c0b02
#define RMI_CHIP_XLR308_B1 0x0c0603
#define RMI_CHIP_XLR508_B1 0x0c0703
#define RMI_CHIP_XLR516_B1 0x0c0803
#define RMI_CHIP_XLR532_B1 0x0c0903
#define RMI_CHIP_XLR716_B1 0x0c0a03
#define RMI_CHIP_XLR732_B1 0x0c0b03
#define RMI_CHIP_XLR308_B2 0x0c0604
#define RMI_CHIP_XLR508_B2 0x0c0704
#define RMI_CHIP_XLR516_B2 0x0c0804
#define RMI_CHIP_XLR532_B2 0x0c0904
#define RMI_CHIP_XLR716_B2 0x0c0a04
#define RMI_CHIP_XLR732_B2 0x0c0b04
#define RMI_CHIP_XLR308_C0 0x0c0705
#define RMI_CHIP_XLR508_C0 0x0c0b05
#define RMI_CHIP_XLR516_C0 0x0c0a05
#define RMI_CHIP_XLR532_C0 0x0c0805
#define RMI_CHIP_XLR716_C0 0x0c0205
#define RMI_CHIP_XLR732_C0 0x0c0005
#define RMI_CHIP_XLR308_C1 0x0c0706
#define RMI_CHIP_XLR508_C1 0x0c0b06
#define RMI_CHIP_XLR516_C1 0x0c0a06
#define RMI_CHIP_XLR532_C1 0x0c0806
#define RMI_CHIP_XLR716_C1 0x0c0206
#define RMI_CHIP_XLR732_C1 0x0c0006
#define RMI_CHIP_XLR308_C2 0x0c0707
#define RMI_CHIP_XLR508_C2 0x0c0b07
#define RMI_CHIP_XLR516_C2 0x0c0a07
#define RMI_CHIP_XLR532_C2 0x0c0807
#define RMI_CHIP_XLR716_C2 0x0c0207
#define RMI_CHIP_XLR732_C2 0x0c0007
#define RMI_CHIP_XLR308_C3 0x0c0708
#define RMI_CHIP_XLR508_C3 0x0c0b08
#define RMI_CHIP_XLR516_C3 0x0c0a08
#define RMI_CHIP_XLR532_C3 0x0c0808
#define RMI_CHIP_XLR716_C3 0x0c0208
#define RMI_CHIP_XLR732_C3 0x0c0008
#define RMI_CHIP_XLR308_C4 0x0c0709
#define RMI_CHIP_XLR508_C4 0x0c0b09
#define RMI_CHIP_XLR516_C4 0x0c0a09
#define RMI_CHIP_XLR532_C4 0x0c0809
#define RMI_CHIP_XLR716_C4 0x0c0209
#define RMI_CHIP_XLR732_C4 0x0c0009
#define RMI_CHIP_XLS608_A0 0x0c8000
#define RMI_CHIP_XLS408_A0 0x0c8800
#define RMI_CHIP_XLS404_A0 0x0c8c00
#define RMI_CHIP_XLS208_A0 0x0c8e00
#define RMI_CHIP_XLS204_A0 0x0c8f00
#define RMI_CHIP_XLS608_A1 0x0c8001
#define RMI_CHIP_XLS408_A1 0x0c8801
#define RMI_CHIP_XLS404_A1 0x0c8c01
#define RMI_CHIP_XLS208_A1 0x0c8e01
#define RMI_CHIP_XLS204_A1 0x0c8f01
static __inline__ unsigned int
xlr_revision(void)
{
return mips_rd_prid() & 0xff00ff;
}
static __inline__ unsigned int
xlr_is_xls(void)
{
uint32_t prid = mips_rd_prid();
return (prid & 0xf000) == 0x8000 || (prid & 0xf000) == 0x4000;
}
static __inline__ int
xlr_revision_a0(void)
{
return xlr_revision() == 0x0c0000;
}
static __inline__ int
xlr_revision_b0(void)
{
return xlr_revision() == 0x0c0002;
}
static __inline__ int
xlr_revision_b1(void)
{
return xlr_revision() == 0x0c0003;
}
static __inline__ int
xlr_board_atx_i(void)
{
return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_I;
}
static __inline__ int
xlr_board_atx_ii(void)
{
return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_II;
}
static __inline__ int
xlr_board_atx_ii_b(void)
{
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_II)
&& (xlr_boot1_info.board_minor_version == 1);
}
static __inline__ int
xlr_board_atx_iii(void)
{
return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III;
}
static __inline__ int
xlr_board_atx_iv(void)
{
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_IV)
&& (xlr_boot1_info.board_minor_version == 0); }
static __inline__ int
xlr_board_atx_iv_b(void)
{
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_IV)
&& (xlr_boot1_info.board_minor_version == 1);
}
static __inline__ int
xlr_board_atx_v(void)
{
return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_V;
}
static __inline__ int
xlr_board_atx_vi(void)
{
return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI;
}
static __inline__ int
xlr_board_atx_iii_256(void)
{
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III)
&& (xlr_boot1_info.board_minor_version == 0);
}
static __inline__ int
xlr_board_atx_iii_512(void)
{
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III)
&& (xlr_boot1_info.board_minor_version == 1);
}
static __inline__ int
xlr_board_atx_v_512(void)
{
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_V)
&& (xlr_boot1_info.board_minor_version == 1);
}
static __inline__ int
xlr_board_pci(void)
{
return (xlr_board_atx_iii_256() || xlr_board_atx_iii_512()
|| xlr_board_atx_v_512());
}
static __inline__ int
xlr_is_xls2xx(void)
{
uint32_t chipid = mips_rd_prid() & 0xffffff00U;
return chipid == 0x0c8e00 || chipid == 0x0c8f00;
}
static __inline__ int
xlr_is_xls4xx(void)
{
uint32_t chipid = mips_rd_prid() & 0xffffff00U;
return chipid == 0x0c8800 || chipid == 0x0c8c00;
}
/* all our knowledge of chip and board that cannot be detected run-time goes here */
enum gmac_block_types { XLR_GMAC, XLR_XGMAC, XLR_SPI4};
enum gmac_block_modes { XLR_RGMII, XLR_SGMII, XLR_PORT0_RGMII };
struct xlr_board_info {
int is_xls;
int nr_cpus;
int usb; /* usb enabled ? */
int cfi; /* compact flash driver for NOR? */
int pci_irq;
struct stn_cc **credit_configs; /* pointer to Core station credits */
struct bucket_size *bucket_sizes; /* pointer to Core station bucket */
int *msgmap; /* mapping of message station to devices */
int gmacports; /* number of gmac ports on the board */
struct xlr_gmac_block_t {
int type; /* see enum gmac_block_types */
unsigned int enabled; /* mask of ports enabled */
struct stn_cc *credit_config; /* credit configuration */
int station_txbase; /* station id for tx */
int station_rfr; /* free desc bucket */
int mode; /* see gmac_block_modes */
uint32_t baseaddr; /* IO base */
int baseirq; /* first irq for this block, the rest are in sequence */
int baseinst; /* the first rge unit for this block */
} gmac_block [3];
};
extern struct xlr_board_info xlr_board_info;
int xlr_board_info_setup(void);
#endif

213
sys/mips/rmi/clock.c Normal file
View File

@ -0,0 +1,213 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/queue.h>
#include <sys/smp.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/timetc.h>
#include <sys/module.h>
#include <sys/stdint.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <sys/systm.h>
#include <sys/clock.h>
#include <machine/clock.h>
#include <machine/md_var.h>
#include <machine/hwfunc.h>
#include <machine/intr_machdep.h>
#include <mips/xlr/iomap.h>
#include <mips/xlr/clock.h>
#include <mips/xlr/interrupt.h>
#include <mips/xlr/pic.h>
#include <mips/xlr/shared_structs.h>
#ifdef XLR_PERFMON
#include <mips/xlr/perfmon.h>
#endif
int hw_clockrate;
SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD, &hw_clockrate,
0, "CPU instruction clock rate");
#define STAT_PROF_CLOCK_SCALE_FACTOR 8
static int scale_factor;
static int count_scale_factor[32];
uint64_t platform_get_frequency()
{
return XLR_PIC_HZ;
}
/*
* count_compare_clockhandler:
*
* Handle the clock interrupt when count becomes equal to
* compare.
*/
void
count_compare_clockhandler(struct trapframe *tf)
{
int cpu = PCPU_GET(cpuid);
uint32_t cycles;
critical_enter();
if (cpu == 0) {
mips_wr_compare(0);
}
else {
count_scale_factor[cpu]++;
cycles = mips_rd_count();
cycles += XLR_CPU_HZ/hz;
mips_wr_compare(cycles);
hardclock_process((struct clockframe *)tf);
if (count_scale_factor[cpu] == STAT_PROF_CLOCK_SCALE_FACTOR) {
statclock((struct clockframe *)tf);
if(profprocs != 0) {
profclock((struct clockframe *)tf);
}
count_scale_factor[cpu] = 0;
}
/* If needed , handle count compare tick skew here */
}
critical_exit();
}
void
pic_hardclockhandler(struct trapframe *tf)
{
int cpu = PCPU_GET(cpuid);
critical_enter();
if (cpu == 0) {
scale_factor++;
hardclock((struct clockframe *)tf);
if (scale_factor == STAT_PROF_CLOCK_SCALE_FACTOR) {
statclock((struct clockframe *)tf);
if(profprocs != 0) {
profclock((struct clockframe *)tf);
}
scale_factor = 0;
}
#ifdef XLR_PERFMON
if (xlr_perfmon_started)
xlr_perfmon_clockhandler();
#endif
}
else {
/* If needed , handle count compare tick skew here */
}
critical_exit();
}
void
pic_timecounthandler(struct trapframe *tf)
{
}
void
platform_initclocks(void)
{
int cpu = PCPU_GET(cpuid);
void *cookie;
/* Note: Passing #3 as NULL ensures that clockhandler
* gets called with trapframe
*/
/* profiling/process accounting timer interrupt for non-zero cpus */
cpu_establish_intr("compare", IRQ_TIMER,
(driver_intr_t *)count_compare_clockhandler,
NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL);
/* timekeeping timer interrupt for cpu 0 */
cpu_establish_intr("hardclk", PIC_TIMER_7_IRQ,
(driver_intr_t *)pic_hardclockhandler,
NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL);
/* this is used by timecounter */
cpu_establish_intr("timecount", PIC_TIMER_6_IRQ,
(driver_intr_t *)pic_timecounthandler,
NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL);
if (cpu == 0) {
__uint64_t maxval = XLR_PIC_HZ/hz;
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
stathz = hz / STAT_PROF_CLOCK_SCALE_FACTOR;
profhz = stathz;
/* Setup PIC Interrupt */
mtx_lock_spin(&xlr_pic_lock);
xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff));
xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff);
xlr_write_reg(mmio, PIC_IRT_0_TIMER_7, (1 << cpu));
xlr_write_reg(mmio, PIC_IRT_1_TIMER_7, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_7_IRQ));
pic_update_control(1<<(8+7));
xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff));
xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0x0) & 0xffffffff);
xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu));
xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_6_IRQ));
pic_update_control(1<<(8+6));
mtx_unlock_spin(&xlr_pic_lock);
} else {
/* Setup count-compare interrupt for vcpu[1-31] */
mips_wr_compare((xlr_boot1_info.cpu_frequency)/hz);
}
}
unsigned __attribute__((no_instrument_function))
platform_get_timecount(struct timecounter *tc)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
return 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0);
}

40
sys/mips/rmi/clock.h Normal file
View File

@ -0,0 +1,40 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#ifndef _RMI_CLOCK_H_
#define _RMI_CLOCK_H_
#define XLR_PIC_HZ 66000000U
#define XLR_CPU_HZ (xlr_boot1_info.cpu_frequency)
void count_compare_clockhandler(struct trapframe *);
void pic_hardclockhandler(struct trapframe *);
void pic_timecounthandler(struct trapframe *);
#endif /* _RMI_CLOCK_H_ */

103
sys/mips/rmi/debug.h Executable file
View File

@ -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

43
sys/mips/rmi/interrupt.h Normal file
View File

@ -0,0 +1,43 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#ifndef _RMI_INTERRUPT_H_
#define _RMI_INTERRUPT_H_
/* Defines for the IRQ numbers */
#define IRQ_DUMMY_UART 2
#define IRQ_IPI_SMP_FUNCTION 3
#define IRQ_IPI_SMP_RESCHEDULE 4
#define IRQ_REMOTE_DEBUG 5
#define IRQ_MSGRING 6
#define IRQ_TIMER 7
#endif /* _RMI_INTERRUPT_H_ */

272
sys/mips/rmi/iodi.c Normal file
View File

@ -0,0 +1,272 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#define __RMAN_RESOURCE_VISIBLE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/reboot.h>
#include <sys/types.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/module.h>
#include <machine/cpu.h>
#include <machine/bus.h>
#include <machine/bus.h>
#include <machine/intr_machdep.h>
#include <mips/xlr/iomap.h>
#include <mips/xlr/pic.h>
#include <mips/xlr/board.h>
#include <sys/rman.h>
extern void iodi_activateirqs(void);
extern bus_space_tag_t uart_bus_space_mem;
static struct resource *iodi_alloc_resource(device_t, device_t, int, int *,
u_long, u_long, u_long, u_int);
static int iodi_activate_resource(device_t, device_t, int, int,
struct resource *);
static int iodi_setup_intr(device_t, device_t, struct resource *, int,
driver_intr_t *, void *, void **);
struct iodi_softc *iodi_softc; /* There can be only one. */
static void pic_usb_ack(void *arg)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
int irq = PIC_USB_IRQ ;
mtx_lock_spin(&xlr_pic_lock);
xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
mtx_unlock_spin(&xlr_pic_lock);
}
static int
iodi_setup_intr(device_t dev, device_t child,
struct resource *ires, int flags, driver_intr_t *intr, void *arg,
void **cookiep)
{
int level;
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
xlr_reg_t reg;
/* FIXME is this the right place to fiddle with PIC? */
if (strcmp(device_get_name(child),"uart") == 0) {
/* FIXME uart 1? */
mtx_lock_spin(&xlr_pic_lock);
level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_UART_0_INDEX);
xlr_write_reg(mmio, PIC_IRT_0_UART_0, 0x01);
xlr_write_reg(mmio, PIC_IRT_1_UART_0, ((1 << 31) | (level<<30)|(1<<6)|(PIC_UART_0_IRQ)));
mtx_unlock_spin(&xlr_pic_lock);
cpu_establish_intr("uart", PIC_UART_0_IRQ,
(driver_intr_t *)intr, (void *)arg, flags, cookiep,
NULL, NULL);
} else if (strcmp(device_get_name(child),"rge") == 0) {
mtx_lock_spin(&xlr_pic_lock);
reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + ires->r_flags - PIC_IRQ_BASE);
xlr_write_reg(mmio, PIC_IRT_1_BASE + ires->r_flags - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31));
mtx_unlock_spin(&xlr_pic_lock);
cpu_establish_intr("rge", ires->r_flags,
(driver_intr_t *)intr, (void *)arg,
flags, cookiep, NULL, NULL);
} else if (strcmp(device_get_name(child),"ehci") == 0) {
mtx_lock_spin(&xlr_pic_lock);
reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE);
xlr_write_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31));
mtx_unlock_spin(&xlr_pic_lock);
cpu_establish_intr("ehci", PIC_USB_IRQ,
(driver_intr_t *)intr, (void *)arg,
flags, cookiep, (flags & INTR_FAST)? NULL: pic_usb_ack , NULL);
}
BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, intr, arg,
cookiep);
return (0);
}
static struct resource *
iodi_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct resource *res = malloc(sizeof(*res), M_DEVBUF, M_WAITOK);
int unit;
#ifdef DEBUG
switch (type) {
case SYS_RES_IRQ:
device_printf(bus, "IRQ resource - for %s %lx-%lx\n",
device_get_nameunit(child), start, end);
break;
case SYS_RES_IOPORT:
device_printf(bus, "IOPORT resource - for %s %lx-%lx\n",
device_get_nameunit(child), start, end);
break;
case SYS_RES_MEMORY:
device_printf(bus, "MEMORY resource - for %s %lx-%lx\n",
device_get_nameunit(child), start, end);
break;
}
#endif
if (strcmp(device_get_name(child),"uart") == 0) {
if ((unit=device_get_unit(child)) == 0) { /* uart 0 */
res->r_bushandle = (xlr_io_base + XLR_IO_UART_0_OFFSET);
}
else if ( unit == 1) {
res->r_bushandle = (xlr_io_base + XLR_IO_UART_1_OFFSET);
}
else
printf("%s: Unknown uart unit\n", __FUNCTION__);
res->r_bustag = uart_bus_space_mem;
} else if (strcmp(device_get_name(child),"ehci") == 0) {
res->r_bushandle = 0xbef24000;
res->r_bustag = MIPS_BUS_SPACE_PCI;
} else if (strcmp(device_get_name(child),"cfi") == 0) {
res->r_bushandle = 0xbc000000;
res->r_bustag = 0;
}
res->r_start = *rid;
return (res);
}
static int
iodi_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
return (0);
}
/* prototypes */
static int iodi_probe(device_t);
static int iodi_attach(device_t);
static void iodi_identify(driver_t *, device_t);
int
iodi_probe(device_t dev)
{
return 0;
}
void
iodi_identify(driver_t *driver, device_t parent)
{
BUS_ADD_CHILD(parent, 0, "iodi", 0);
}
int
iodi_attach(device_t dev)
{
device_t tmpd;
/*
* Attach each devices
*/
device_add_child(dev, "uart", 0);
device_add_child(dev, "xlr_i2c", 0);
if (xlr_board_info.usb)
device_add_child(dev, "ehci", 0);
if (xlr_board_info.cfi)
device_add_child(dev, "cfi", 0);
if (xlr_board_info.gmac_block[0].enabled) {
tmpd = device_add_child(dev, "rge", 0);
device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
tmpd = device_add_child(dev, "rge", 1);
device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
tmpd = device_add_child(dev, "rge", 2);
device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
tmpd = device_add_child(dev, "rge", 3);
device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
}
if (xlr_board_info.gmac_block[1].enabled) {
if (xlr_board_info.gmac_block[1].type == XLR_GMAC) {
tmpd = device_add_child(dev, "rge", 4);
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
tmpd = device_add_child(dev, "rge", 5);
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
tmpd = device_add_child(dev, "rge", 6);
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
tmpd = device_add_child(dev, "rge", 7);
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
} else if (xlr_board_info.gmac_block[1].type == XLR_XGMAC) {
#if 0 /* XGMAC not yet */
tmpd = device_add_child(dev, "rge", 4);
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
tmpd = device_add_child(dev, "rge", 5);
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
#endif
} else
device_printf(dev, "Unknown type of gmac 1\n");
}
bus_generic_probe(dev);
bus_generic_attach(dev);
return 0;
}
static device_method_t iodi_methods[] = {
DEVMETHOD(device_probe, iodi_probe),
DEVMETHOD(device_attach, iodi_attach),
DEVMETHOD(device_identify, iodi_identify),
DEVMETHOD(bus_alloc_resource, iodi_alloc_resource),
DEVMETHOD(bus_activate_resource, iodi_activate_resource),
DEVMETHOD(bus_setup_intr, iodi_setup_intr),
{0, 0},
};
static driver_t iodi_driver = {
"iodi",
iodi_methods,
1 /* no softc */
};
static devclass_t iodi_devclass;
DRIVER_MODULE(iodi, nexus, iodi_driver, iodi_devclass, 0, 0);

110
sys/mips/rmi/iomap.h Normal file
View File

@ -0,0 +1,110 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#ifndef _RMI_IOMAP_H_
#define _RMI_IOMAP_H_
#include <machine/endian.h>
#define DEFAULT_XLR_IO_BASE 0xffffffffbef00000ULL
#define XLR_IO_SIZE 0x1000
#define XLR_IO_BRIDGE_OFFSET 0x00000
#define XLR_IO_DDR2_CHN0_OFFSET 0x01000
#define XLR_IO_DDR2_CHN1_OFFSET 0x02000
#define XLR_IO_DDR2_CHN2_OFFSET 0x03000
#define XLR_IO_DDR2_CHN3_OFFSET 0x04000
#define XLR_IO_RLD2_CHN0_OFFSET 0x05000
#define XLR_IO_RLD2_CHN1_OFFSET 0x06000
#define XLR_IO_SRAM_OFFSET 0x07000
#define XLR_IO_PIC_OFFSET 0x08000
#define XLR_IO_PCIX_OFFSET 0x09000
#define XLR_IO_HT_OFFSET 0x0A000
#define XLR_IO_SECURITY_OFFSET 0x0B000
#define XLR_IO_GMAC_0_OFFSET 0x0C000
#define XLR_IO_GMAC_1_OFFSET 0x0D000
#define XLR_IO_GMAC_2_OFFSET 0x0E000
#define XLR_IO_GMAC_3_OFFSET 0x0F000
#define XLR_IO_SPI4_0_OFFSET 0x10000
#define XLR_IO_XGMAC_0_OFFSET 0x11000
#define XLR_IO_SPI4_1_OFFSET 0x12000
#define XLR_IO_XGMAC_1_OFFSET 0x13000
#define XLR_IO_UART_0_OFFSET 0x14000
#define XLR_IO_UART_1_OFFSET 0x15000
#define XLR_IO_I2C_0_OFFSET 0x16000
#define XLR_IO_I2C_1_OFFSET 0x17000
#define XLR_IO_GPIO_OFFSET 0x18000
#define XLR_IO_FLASH_OFFSET 0x19000
#define XLR_IO_TB_OFFSET 0x1C000
#define XLR_IO_GMAC_4_OFFSET 0x20000
#define XLR_IO_GMAC_5_OFFSET 0x21000
#define XLR_IO_GMAC_6_OFFSET 0x22000
#define XLR_IO_GMAC_7_OFFSET 0x23000
#define XLR_IO_PCIE_0_OFFSET 0x1E000
#define XLR_IO_PCIE_1_OFFSET 0x1F000
#define XLR_IO_USB_0_OFFSET 0x24000
#define XLR_IO_USB_1_OFFSET 0x25000
#define XLR_IO_COMP_OFFSET 0x1d000
/* Base Address (Virtual) of the PCI Config address space
* For now, choose 256M phys in kseg1 = 0xA0000000 + (1<<28)
* Config space spans 256 (num of buses) * 256 (num functions) * 256 bytes
* ie 1<<24 = 16M
*/
#define DEFAULT_PCI_CONFIG_BASE 0x18000000
#define DEFAULT_HT_TYPE0_CFG_BASE 0x16000000
#define DEFAULT_HT_TYPE1_CFG_BASE 0x17000000
typedef volatile __uint32_t xlr_reg_t;
extern unsigned long xlr_io_base;
#define xlr_io_mmio(offset) ((xlr_reg_t *)(xlr_io_base+(offset)))
#define xlr_read_reg(base, offset) (__ntohl((base)[(offset)]))
#define xlr_write_reg(base, offset, value) ((base)[(offset)] = __htonl((value)))
extern void on_chip_init(void);
#endif /* _RMI_IOMAP_H_ */

318
sys/mips/rmi/msgring.c Normal file
View File

@ -0,0 +1,318 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
/**********************************************************
* -----------------DO NOT EDIT THIS FILE------------------
* This file has been autogenerated by the build process
* from "msgring.cfg"
**********************************************************/
#include <mips/xlr/msgring.h>
struct bucket_size bucket_sizes = {
{
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 0,
32, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 0,
0, 32, 32, 32, 32, 32, 0, 32,
0, 0, 0, 0, 0, 0, 0, 0,
0, 32, 0, 32, 0, 0, 0, 0,
128, 0, 0, 0, 128, 0, 0, 0,
}
};
struct stn_cc cc_table_cpu_0 = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 4 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{0, 2 , 4 , 4 , 4 , 4 , 0 , 2 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 2 , 0 , 2 , 0 , 0 , 0 , 0 },
{16, 0 , 0 , 0 , 16 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_cpu_1 = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{0, 2 , 4 , 4 , 4 , 4 , 0 , 2 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 2 , 0 , 2 , 0 , 0 , 0 , 0 },
{16, 0 , 0 , 0 , 16 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_cpu_2 = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{0, 4 , 4 , 4 , 4 , 4 , 0 , 4 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 0 , 4 , 0 , 0 , 0 , 0 },
{16, 0 , 0 , 0 , 16 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_cpu_3 = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{0, 4 , 4 , 4 , 4 , 4 , 0 , 4 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 0 , 4 , 0 , 0 , 0 , 0 },
{16, 0 , 0 , 0 , 16 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_cpu_4 = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{0, 4 , 4 , 4 , 4 , 4 , 0 , 4 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 0 , 4 , 0 , 0 , 0 , 0 },
{16, 0 , 0 , 0 , 16 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_cpu_5 = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{0, 4 , 4 , 4 , 4 , 4 , 0 , 4 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 0 , 4 , 0 , 0 , 0 , 0 },
{16, 0 , 0 , 0 , 16 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_cpu_6 = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{0, 4 , 4 , 4 , 4 , 4 , 0 , 4 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 0 , 4 , 0 , 0 , 0 , 0 },
{16, 0 , 0 , 0 , 16 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_cpu_7 = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{4, 2 , 2 , 2 , 2 , 2 , 2 , 2 },
{2, 2 , 2 , 2 , 2 , 2 , 2 , 0 },
{0, 4 , 4 , 4 , 4 , 4 , 0 , 4 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 0 , 4 , 0 , 0 , 0 , 0 },
{16, 0 , 0 , 0 , 16 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_xgs_0 = {{
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_xgs_1 = {{
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 4 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_gmac = {{
{8, 8 , 8 , 8 , 16 , 16 , 16 , 16 },
{8, 8 , 8 , 8 , 16 , 16 , 16 , 16 },
{8, 8 , 8 , 8 , 16 , 16 , 16 , 16 },
{8, 8 , 8 , 8 , 16 , 16 , 16 , 16 },
{8, 8 , 8 , 8 , 16 , 16 , 16 , 16 },
{8, 8 , 8 , 8 , 16 , 16 , 16 , 16 },
{8, 8 , 8 , 8 , 16 , 16 , 16 , 16 },
{8, 8 , 8 , 8 , 16 , 16 , 16 , 16 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 0 , 0 , 0 , 0 , 0 , 4 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_dma = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc cc_table_sec = {{
{8, 8 , 8 , 8 , 0 , 0 , 0 , 0 },
{8, 8 , 8 , 4 , 0 , 0 , 0 , 0 },
{8, 8 , 8 , 8 , 0 , 0 , 0 , 0 },
{8, 8 , 8 , 8 , 0 , 0 , 0 , 0 },
{8, 8 , 8 , 8 , 0 , 0 , 0 , 0 },
{8, 8 , 8 , 8 , 0 , 0 , 0 , 0 },
{8, 8 , 8 , 8 , 0 , 0 , 0 , 0 },
{8, 8 , 8 , 8 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
}};

1182
sys/mips/rmi/msgring.cfg Normal file

File diff suppressed because it is too large Load Diff

507
sys/mips/rmi/msgring.h Executable file
View File

@ -0,0 +1,507 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#ifndef _RMI_MSGRING_H_
#define _RMI_MSGRING_H_
#include <mips/xlr/xlrconfig.h>
#define MSGRNG_TX_BUF_REG 0
#define MSGRNG_RX_BUF_REG 1
#define MSGRNG_MSG_STATUS_REG 2
#define MSGRNG_MSG_CONFIG_REG 3
#define MSGRNG_MSG_BUCKSIZE_REG 4
#define MSGRNG_CC_0_REG 16
#define MSGRNG_CC_1_REG 17
#define MSGRNG_CC_2_REG 18
#define MSGRNG_CC_3_REG 19
#define MSGRNG_CC_4_REG 20
#define MSGRNG_CC_5_REG 21
#define MSGRNG_CC_6_REG 22
#define MSGRNG_CC_7_REG 23
#define MSGRNG_CC_8_REG 24
#define MSGRNG_CC_9_REG 25
#define MSGRNG_CC_10_REG 26
#define MSGRNG_CC_11_REG 27
#define MSGRNG_CC_12_REG 28
#define MSGRNG_CC_13_REG 29
#define MSGRNG_CC_14_REG 30
#define MSGRNG_CC_15_REG 31
#define msgrng_read_status() read_c2_register32(MSGRNG_MSG_STATUS_REG, 0)
#define msgrng_read_config() read_c2_register32(MSGRNG_MSG_CONFIG_REG, 0)
#define msgrng_write_config(value) write_c2_register32(MSGRNG_MSG_CONFIG_REG, 0, value)
#define msgrng_read_bucksize(bucket) read_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, bucket)
#define msgrng_write_bucksize(bucket, value) write_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, bucket, value)
#define msgrng_read_cc(reg, pri) read_c2_register32(reg, pri)
#define msgrng_write_cc(reg, value, pri) write_c2_register32(reg, pri, value)
#define msgrng_load_rx_msg0() read_c2_register64(MSGRNG_RX_BUF_REG, 0)
#define msgrng_load_rx_msg1() read_c2_register64(MSGRNG_RX_BUF_REG, 1)
#define msgrng_load_rx_msg2() read_c2_register64(MSGRNG_RX_BUF_REG, 2)
#define msgrng_load_rx_msg3() read_c2_register64(MSGRNG_RX_BUF_REG, 3)
#define msgrng_load_tx_msg0(value) write_c2_register64(MSGRNG_TX_BUF_REG, 0, value)
#define msgrng_load_tx_msg1(value) write_c2_register64(MSGRNG_TX_BUF_REG, 1, value)
#define msgrng_load_tx_msg2(value) write_c2_register64(MSGRNG_TX_BUF_REG, 2, value)
#define msgrng_load_tx_msg3(value) write_c2_register64(MSGRNG_TX_BUF_REG, 3, value)
/* Station IDs */
#define MSGRNG_STNID_CPU0 0x00
#define MSGRNG_STNID_CPU1 0x08
#define MSGRNG_STNID_CPU2 0x10
#define MSGRNG_STNID_CPU3 0x18
#define MSGRNG_STNID_CPU4 0x20
#define MSGRNG_STNID_CPU5 0x28
#define MSGRNG_STNID_CPU6 0x30
#define MSGRNG_STNID_CPU7 0x38
#define MSGRNG_STNID_XGS0_TX 64
#define MSGRNG_STNID_XMAC0_00_TX 64
#define MSGRNG_STNID_XMAC0_01_TX 65
#define MSGRNG_STNID_XMAC0_02_TX 66
#define MSGRNG_STNID_XMAC0_03_TX 67
#define MSGRNG_STNID_XMAC0_04_TX 68
#define MSGRNG_STNID_XMAC0_05_TX 69
#define MSGRNG_STNID_XMAC0_06_TX 70
#define MSGRNG_STNID_XMAC0_07_TX 71
#define MSGRNG_STNID_XMAC0_08_TX 72
#define MSGRNG_STNID_XMAC0_09_TX 73
#define MSGRNG_STNID_XMAC0_10_TX 74
#define MSGRNG_STNID_XMAC0_11_TX 75
#define MSGRNG_STNID_XMAC0_12_TX 76
#define MSGRNG_STNID_XMAC0_13_TX 77
#define MSGRNG_STNID_XMAC0_14_TX 78
#define MSGRNG_STNID_XMAC0_15_TX 79
#define MSGRNG_STNID_XGS1_TX 80
#define MSGRNG_STNID_XMAC1_00_TX 80
#define MSGRNG_STNID_XMAC1_01_TX 81
#define MSGRNG_STNID_XMAC1_02_TX 82
#define MSGRNG_STNID_XMAC1_03_TX 83
#define MSGRNG_STNID_XMAC1_04_TX 84
#define MSGRNG_STNID_XMAC1_05_TX 85
#define MSGRNG_STNID_XMAC1_06_TX 86
#define MSGRNG_STNID_XMAC1_07_TX 87
#define MSGRNG_STNID_XMAC1_08_TX 88
#define MSGRNG_STNID_XMAC1_09_TX 89
#define MSGRNG_STNID_XMAC1_10_TX 90
#define MSGRNG_STNID_XMAC1_11_TX 91
#define MSGRNG_STNID_XMAC1_12_TX 92
#define MSGRNG_STNID_XMAC1_13_TX 93
#define MSGRNG_STNID_XMAC1_14_TX 94
#define MSGRNG_STNID_XMAC1_15_TX 95
#define MSGRNG_STNID_GMAC 96
#define MSGRNG_STNID_GMACJFR_0 96
#define MSGRNG_STNID_GMACRFR_0 97
#define MSGRNG_STNID_GMACTX0 98
#define MSGRNG_STNID_GMACTX1 99
#define MSGRNG_STNID_GMACTX2 100
#define MSGRNG_STNID_GMACTX3 101
#define MSGRNG_STNID_GMACJFR_1 102
#define MSGRNG_STNID_GMACRFR_1 103
#define MSGRNG_STNID_DMA 104
#define MSGRNG_STNID_DMA_0 104
#define MSGRNG_STNID_DMA_1 105
#define MSGRNG_STNID_DMA_2 106
#define MSGRNG_STNID_DMA_3 107
#define MSGRNG_STNID_XGS0FR 112
#define MSGRNG_STNID_XMAC0JFR 112
#define MSGRNG_STNID_XMAC0RFR 113
#define MSGRNG_STNID_XGS1FR 114
#define MSGRNG_STNID_XMAC1JFR 114
#define MSGRNG_STNID_XMAC1RFR 115
#define MSGRNG_STNID_SEC 120
#define MSGRNG_STNID_SEC0 120
#define MSGRNG_STNID_SEC1 121
#define MSGRNG_STNID_SEC2 122
#define MSGRNG_STNID_SEC3 123
#define MSGRNG_STNID_PK0 124
#define MSGRNG_STNID_SEC_RSA 124
#define MSGRNG_STNID_SEC_RSVD0 125
#define MSGRNG_STNID_SEC_RSVD1 126
#define MSGRNG_STNID_SEC_RSVD2 127
#define MSGRNG_STNID_GMAC1 80
#define MSGRNG_STNID_GMAC1_FR_0 81
#define MSGRNG_STNID_GMAC1_TX0 82
#define MSGRNG_STNID_GMAC1_TX1 83
#define MSGRNG_STNID_GMAC1_TX2 84
#define MSGRNG_STNID_GMAC1_TX3 85
#define MSGRNG_STNID_GMAC1_FR_1 87
#define MSGRNG_STNID_GMAC0 96
#define MSGRNG_STNID_GMAC0_FR_0 97
#define MSGRNG_STNID_GMAC0_TX0 98
#define MSGRNG_STNID_GMAC0_TX1 99
#define MSGRNG_STNID_GMAC0_TX2 100
#define MSGRNG_STNID_GMAC0_TX3 101
#define MSGRNG_STNID_GMAC0_FR_1 103
#define MSGRNG_STNID_CMP_0 108
#define MSGRNG_STNID_CMP_1 109
#define MSGRNG_STNID_CMP_2 110
#define MSGRNG_STNID_CMP_3 111
#define MSGRNG_STNID_PCIE_0 116
#define MSGRNG_STNID_PCIE_1 117
#define MSGRNG_STNID_PCIE_2 118
#define MSGRNG_STNID_PCIE_3 119
#define MSGRNG_STNID_XLS_PK0 121
#define MSGRNG_CODE_MAC 0
#define MSGRNG_CODE_XGMAC 2
#define MSGRNG_CODE_SEC 0
#define MSGRNG_CODE_BOOT_WAKEUP 200
#define MSGRNG_CODE_SPI4 3
static inline int msgrng_xgmac_stid_rfr(int id)
{
return !id ? MSGRNG_STNID_XMAC0RFR : MSGRNG_STNID_XMAC1RFR;
}
static inline int msgrng_xgmac_stid_jfr(int id)
{
return !id ? MSGRNG_STNID_XMAC0JFR : MSGRNG_STNID_XMAC1JFR;
}
static inline int msgrng_xgmac_stid_tx(int id)
{
return !id ? MSGRNG_STNID_XMAC0_00_TX : MSGRNG_STNID_XMAC1_00_TX;
}
static inline int msgrng_gmac_stid_rfr(int id)
{
return (MSGRNG_STNID_GMACRFR_0);
}
static inline int msgrng_gmac_stid_rfr_split_mode(int id)
{
return ((id>>1)?MSGRNG_STNID_GMACRFR_1:MSGRNG_STNID_GMACRFR_0);
}
static inline int msgrng_gmac_stid_jfr(int id)
{
return MSGRNG_STNID_GMACJFR_0;
}
static inline int msgrng_gmac_stid_jfr_split_mode(int id)
{
return ((id>>1)?MSGRNG_STNID_GMACJFR_1:MSGRNG_STNID_GMACJFR_0);
}
static inline int msgrng_gmac_stid_tx(int id)
{
return (MSGRNG_STNID_GMACTX0 + id);
}
static inline void msgrng_send(unsigned int stid)
{
__asm__ volatile (
".set push\n"
".set noreorder\n"
"sync\n"
// "msgsnd %0\n"
"move $8, %0\n"
"c2 0x80001\n"
".set pop\n"
: : "r" (stid) : "$8"
);
}
static inline void msgrng_receive(unsigned int pri)
{
__asm__ volatile (
".set push\n"
".set noreorder\n"
// "msgld %0\n"
"move $8, %0\n"
"c2 0x80002\n"
".set pop\n"
: : "r" (pri) : "$8"
);
}
static inline void msgrng_wait(unsigned int mask)
{
__asm__ volatile (
".set push\n"
".set noreorder\n"
// "msgwait %0\n"
"move $8, %0\n"
"c2 0x80003\n"
".set pop\n"
: :"r" (mask) : "$8"
);
}
#define msgrng_enable(flags) \
do { \
__asm__ volatile ( \
".set push\n\t" \
".set reorder\n\t" \
".set noat\n\t" \
"mfc0 %0, $12\n\t" \
"li $8, 0x40000001\n\t" \
"or $1, %0, $8\n\t" \
"xori $1, 1\n\t" \
".set noreorder\n\t" \
"mtc0 $1, $12\n\t" \
".set\tpop\n\t" \
: "=r" (flags) \
: \
: "$8" \
); \
} while (0)
#define msgrng_disable(flags) __asm__ volatile ( \
"mtc0 %0, $12" : : "r" (flags))
#define msgrng_flags_save(flags) msgrng_enable(flags)
#define msgrng_flags_restore(flags) msgrng_disable(flags)
struct msgrng_msg {
__uint64_t msg0;
__uint64_t msg1;
__uint64_t msg2;
__uint64_t msg3;
};
static inline void message_send_block_fast(int size, unsigned int code, unsigned int stid,
unsigned long long msg0, unsigned long long msg1,
unsigned long long msg2, unsigned long long msg3)
{
__asm__ __volatile__ (".set push\n"
".set noreorder\n"
".set mips64\n"
"dmtc2 %1, $0, 0\n"
"dmtc2 %2, $0, 1\n"
"dmtc2 %3, $0, 2\n"
"dmtc2 %4, $0, 3\n"
"move $8, %0\n"
"1: c2 0x80001\n"
"mfc2 $8, $2\n"
"andi $8, $8, 0x6\n"
"bnez $8, 1b\n"
"move $8, %0\n"
".set pop\n"
:
: "r"(((size-1)<<16)|(code<<8)|stid), "r" (msg0), "r" (msg1), "r"(msg2), "r"(msg3)
: "$8"
);
}
#define message_receive_fast(bucket, size, code, stid, msg0, msg1, msg2, msg3) \
( { unsigned int _status=0, _tmp=0; \
msgrng_receive(bucket); \
while ( (_status=msgrng_read_status()) & 0x08) ; \
_tmp = _status & 0x30; \
if (__builtin_expect((!_tmp), 1)) { \
(size)=((_status & 0xc0)>>6)+1; \
(code)=(_status & 0xff00)>>8; \
(stid)=(_status & 0x7f0000)>>16; \
(msg0)=msgrng_load_rx_msg0(); \
(msg1)=msgrng_load_rx_msg1(); \
(msg2)=msgrng_load_rx_msg2(); \
(msg3)=msgrng_load_rx_msg3(); \
_tmp=0; \
} \
_tmp; \
} )
static __inline__ int message_send(unsigned int size, unsigned int code,
unsigned int stid, struct msgrng_msg *msg)
{
unsigned int dest = 0;
unsigned long long status=0;
int i=0;
msgrng_load_tx_msg0(msg->msg0);
msgrng_load_tx_msg1(msg->msg1);
msgrng_load_tx_msg2(msg->msg2);
msgrng_load_tx_msg3(msg->msg3);
dest = ((size-1)<<16)|(code<<8)|(stid);
//dbg_msg("Sending msg<%Lx,%Lx,%Lx,%Lx> to dest = %x\n",
//msg->msg0, msg->msg1, msg->msg2, msg->msg3, dest);
msgrng_send(dest);
for(i=0;i<16;i++) {
status = msgrng_read_status();
// dbg_msg("status = %Lx\n", status);
if (status & 0x6) {
continue;
}
else break;
}
if (i==16) {
if (dest == 0x61)
//dbg_msg("Processor %x: Unable to send msg to %llx\n", processor_id(), dest);
return status & 0x6;
}
return msgrng_read_status() & 0x06;
}
static __inline__ int message_send_retry(unsigned int size, unsigned int code,
unsigned int stid, struct msgrng_msg *msg)
{
int res = 0;
int retry = 0;
for(;;) {
res = message_send(size, code, stid, msg);
/* retry a pending fail */
if (res & 0x02) continue;
/* credit fail */
if (res & 0x04) retry++;
else break;
if (retry == 4) return res & 0x06;
}
return 0;
}
static __inline__ int message_receive(int pri, int *size, int *code, int *src_id,
struct msgrng_msg *msg)
{
int res = message_receive_fast(pri, *size, *code, *src_id, msg->msg0, msg->msg1, msg->msg2, msg->msg3);
#ifdef MSGRING_DUMP_MESSAGES
if (!res) {
dbg_msg("Received msg <%llx, %llx, %llx, %llx> <%d,%d,%d>\n",
msg->msg0, msg->msg1, msg->msg2, msg->msg3,
*size, *code, *src_id);
}
#endif
return res;
}
#define MSGRNG_STN_RX_QSIZE 256
struct stn_cc {
unsigned short counters[16][8];
};
struct bucket_size {
unsigned short bucket[128];
};
extern struct bucket_size bucket_sizes;
extern struct stn_cc cc_table_cpu_0;
extern struct stn_cc cc_table_cpu_1;
extern struct stn_cc cc_table_cpu_2;
extern struct stn_cc cc_table_cpu_3;
extern struct stn_cc cc_table_cpu_4;
extern struct stn_cc cc_table_cpu_5;
extern struct stn_cc cc_table_cpu_6;
extern struct stn_cc cc_table_cpu_7;
extern struct stn_cc cc_table_xgs_0;
extern struct stn_cc cc_table_xgs_1;
extern struct stn_cc cc_table_gmac;
extern struct stn_cc cc_table_dma;
extern struct stn_cc cc_table_sec;
extern struct bucket_size xls_bucket_sizes;
extern struct stn_cc xls_cc_table_cpu_0;
extern struct stn_cc xls_cc_table_cpu_1;
extern struct stn_cc xls_cc_table_cpu_2;
extern struct stn_cc xls_cc_table_cpu_3;
extern struct stn_cc xls_cc_table_gmac0;
extern struct stn_cc xls_cc_table_gmac1;
extern struct stn_cc xls_cc_table_cmp;
extern struct stn_cc xls_cc_table_pcie;
extern struct stn_cc xls_cc_table_dma;
extern struct stn_cc xls_cc_table_sec;
#define msgrng_access_save(lock, mflags) do { \
mtx_lock_spin(lock); \
msgrng_flags_save(mflags); \
}while(0)
#define msgrng_access_restore(lock, mflags) do { \
msgrng_flags_restore(mflags); \
mtx_unlock_spin(lock); \
}while(0)
#define msgrng_access_enable(mflags) do { \
critical_enter(); \
msgrng_flags_save(mflags); \
} while(0)
#define msgrng_access_disable(mflags) do { \
msgrng_flags_restore(mflags); \
critical_exit(); \
} while(0)
/*
* NOTE: this is not stationid/8, ie the station numbers below are just
* for internal use
*/
enum {
TX_STN_CPU_0,
TX_STN_CPU_1,
TX_STN_CPU_2,
TX_STN_CPU_3,
TX_STN_CPU_4,
TX_STN_CPU_5,
TX_STN_CPU_6,
TX_STN_CPU_7,
TX_STN_GMAC,
TX_STN_DMA,
TX_STN_XGS_0,
TX_STN_XGS_1,
TX_STN_SAE,
TX_STN_GMAC0,
TX_STN_GMAC1,
TX_STN_CDE,
TX_STN_PCIE,
TX_STN_INVALID,
MAX_TX_STNS
};
extern int register_msgring_handler(int major,
void (*action)(int, int,int,int,struct msgrng_msg *, void *),
void *dev_id);
extern void xlr_msgring_cpu_init(void);
extern void xlr_msgring_config(void);
#define cpu_to_msgring_bucket(cpu) ((((cpu) >> 2)<<3)|((cpu) & 0x03))
#endif

218
sys/mips/rmi/msgring_xls.c Normal file
View File

@ -0,0 +1,218 @@
/**********************************************************
* -----------------DO NOT EDIT THIS FILE------------------
* This file has been autogenerated by the build process
* from "msgring_xls.cfg"
**********************************************************/
#include <mips/xlr/msgring.h>
struct bucket_size xls_bucket_sizes = {
{ 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 32, 32, 32, 32, 32, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 32, 32, 32, 32, 32, 0, 0,
64, 64, 64, 64, 32, 32, 32, 32,
0, 0, 0, 0, 0, 0, 0, 0,
128, 128, 0, 0, 0, 0, 0, 0,
}
};
struct stn_cc xls_cc_table_cpu_0 = {{
{1, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 8 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 8 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 8 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 8 , 8 , 8 , 8 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 8 , 8 , 8 , 8 , 0 , 0 },
{16, 16 , 16 , 16 , 16 , 16 , 16 , 16 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{32, 32 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc xls_cc_table_cpu_1 = {{
{1, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 8 , 8 , 8 , 8 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 8 , 8 , 8 , 8 , 0 , 0 },
{16, 16 , 16 , 16 , 16 , 16 , 16 , 16 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{32, 32 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc xls_cc_table_cpu_2 = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 8 , 8 , 8 , 8 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 8 , 8 , 8 , 8 , 0 , 0 },
{16, 16 , 16 , 16 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{32, 32 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc xls_cc_table_cpu_3 = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 8 , 8 , 8 , 8 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 4 , 8 , 8 , 8 , 8 , 0 , 0 },
{16, 16 , 16 , 16 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{32, 32 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc xls_cc_table_gmac0 = {{
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 8 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 8 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc xls_cc_table_gmac1 = {{
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{8, 8 , 8 , 8 , 8 , 8 , 8 , 8 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 8 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 8 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc xls_cc_table_dma = {{
{4, 4 , 4 , 4 , 4 , 4 , 4 , 4 },
{4, 4 , 4 , 2 , 4 , 4 , 4 , 4 },
{4, 4 , 4 , 2 , 4 , 4 , 4 , 4 },
{4, 4 , 4 , 2 , 4 , 4 , 4 , 4 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc xls_cc_table_cmp = {{
{4, 4 , 4 , 4 , 4 , 4 , 4 , 4 },
{4, 4 , 4 , 2 , 4 , 4 , 4 , 4 },
{4, 4 , 4 , 2 , 4 , 4 , 4 , 4 },
{4, 4 , 4 , 2 , 4 , 4 , 4 , 4 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc xls_cc_table_pcie = {{
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
}};
struct stn_cc xls_cc_table_sec = {{
{6, 8 , 8 , 8 , 0 , 0 , 0 , 0 },
{8, 8 , 8 , 4 , 0 , 0 , 0 , 0 },
{8, 8 , 8 , 4 , 0 , 0 , 0 , 0 },
{8, 8 , 8 , 4 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{0, 0 , 0 , 0 , 0 , 0 , 0 , 0 },
}};

563
sys/mips/rmi/msgring_xls.cfg Executable file
View File

@ -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;
}

313
sys/mips/rmi/on_chip.c Normal file
View File

@ -0,0 +1,313 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/limits.h>
#include <sys/bus.h>
#include <machine/reg.h>
#include <machine/cpu.h>
#include <machine/mips_opcode.h>
#include <machine/param.h>
#include <machine/intr_machdep.h>
#include <mips/xlr/interrupt.h>
#include <mips/xlr/msgring.h>
#include <mips/xlr/iomap.h>
#include <mips/xlr/debug.h>
#include <mips/xlr/pic.h>
#include <mips/xlr/board.h>
void disable_msgring_int(void *arg) ;
void enable_msgring_int(void *arg) ;
/* definitions */
struct tx_stn_handler {
void (*action)(int, int, int, int, struct msgrng_msg *, void *);
void *dev_id;
};
/* globals */
static struct tx_stn_handler tx_stn_handlers[MAX_TX_STNS];
#define MSGRNG_CC_INIT_CPU_DEST(dest, counter) \
do { \
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][0], 0 ); \
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][1], 1 ); \
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][2], 2 ); \
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][3], 3 ); \
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][4], 4 ); \
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][5], 5 ); \
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][6], 6 ); \
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][7], 7 ); \
} while(0)
/* make this a read/write spinlock */
static struct mtx msgrng_lock;
static int msgring_int_enabled;
struct mtx xlr_pic_lock;
static int msgring_pop_num_buckets;
static uint32_t msgring_pop_bucket_mask;
static int msgring_int_type;
static int msgring_watermark_count;
static uint32_t msgring_thread_mask;
uint32_t msgrng_msg_cycles = 0;
int xlr_counters[MAXCPU][XLR_MAX_COUNTERS] __aligned(XLR_CACHELINE_SIZE);
void xlr_msgring_handler(struct trapframe *);
void xlr_msgring_cpu_init(void)
{
struct stn_cc *cc_config;
struct bucket_size *bucket_sizes;
int id;
unsigned long flags;
/* if not thread 0 */
if (xlr_thr_id() != 0)
return;
id = xlr_cpu_id();
bucket_sizes = xlr_board_info.bucket_sizes;
cc_config = xlr_board_info.credit_configs[id];
msgrng_flags_save(flags);
/* Message Stations are shared among all threads in a cpu core
* Assume, thread 0 on all cores are always active when more than
* 1 thread is active in a core
*/
msgrng_write_bucksize(0, bucket_sizes->bucket[id*8 + 0]);
msgrng_write_bucksize(1, bucket_sizes->bucket[id*8 + 1]);
msgrng_write_bucksize(2, bucket_sizes->bucket[id*8 + 2]);
msgrng_write_bucksize(3, bucket_sizes->bucket[id*8 + 3]);
msgrng_write_bucksize(4, bucket_sizes->bucket[id*8 + 4]);
msgrng_write_bucksize(5, bucket_sizes->bucket[id*8 + 5]);
msgrng_write_bucksize(6, bucket_sizes->bucket[id*8 + 6]);
msgrng_write_bucksize(7, bucket_sizes->bucket[id*8 + 7]);
MSGRNG_CC_INIT_CPU_DEST(0, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(1, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(2, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(3, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(4, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(5, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(6, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(7, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(8, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(9, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(10, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(11, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(12, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(13, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(14, cc_config->counters);
MSGRNG_CC_INIT_CPU_DEST(15, cc_config->counters);
msgrng_flags_restore(flags);
}
void xlr_msgring_config(void)
{
msgring_int_type = 0x02;
msgring_pop_num_buckets = 8;
msgring_pop_bucket_mask = 0xff;
msgring_watermark_count = 1;
msgring_thread_mask = 0x01;
/* printf("[%s]: int_type = 0x%x, pop_num_buckets=%d, pop_bucket_mask=%x" */
/* "watermark_count=%d, thread_mask=%x\n", __FUNCTION__, */
/* msgring_int_type, msgring_pop_num_buckets, msgring_pop_bucket_mask, */
/* msgring_watermark_count, msgring_thread_mask); */
}
void xlr_msgring_handler(struct trapframe *tf)
{
unsigned long mflags;
int bucket=0;
int size=0, code=0, rx_stid=0, tx_stid=0;
struct msgrng_msg msg;
unsigned int bucket_empty_bm = 0;
unsigned int status=0;
xlr_inc_counter(MSGRNG_INT);
/* TODO: not necessary to disable preemption */
msgrng_flags_save(mflags);
/* First Drain all the high priority messages */
for(;;) {
bucket_empty_bm = (msgrng_read_status() >> 24) & msgring_pop_bucket_mask;
/* all buckets empty, break*/
if ( bucket_empty_bm == msgring_pop_bucket_mask) break;
for(bucket=0; bucket < msgring_pop_num_buckets; bucket++) {
uint32_t cycles = 0;
if ((bucket_empty_bm & (1 << bucket))/*empty*/) continue;
status = message_receive(bucket, &size, &code, &rx_stid, &msg);
if (status) continue;
xlr_inc_counter(MSGRNG_MSG);
msgrng_msg_cycles = mips_rd_count();
cycles = msgrng_msg_cycles;
tx_stid = xlr_board_info.msgmap[rx_stid];
if (!tx_stn_handlers[tx_stid].action) {
printf("[%s]: No Handler for message from stn_id=%d, bucket=%d, "
"size=%d, msg0=%llx, dropping message\n",
__FUNCTION__, tx_stid, bucket, size, msg.msg0);
}
else {
//printf("[%s]: rx_stid = %d\n", __FUNCTION__, rx_stid);
msgrng_flags_restore(mflags);
(*tx_stn_handlers[tx_stid].action)(bucket, size, code, rx_stid,
&msg, tx_stn_handlers[tx_stid].dev_id);
msgrng_flags_save(mflags);
}
xlr_set_counter(MSGRNG_MSG_CYCLES, (read_c0_count()-cycles));
}
}
xlr_set_counter(MSGRNG_EXIT_STATUS, msgrng_read_status());
msgrng_flags_restore(mflags);
//dbg_msg("OUT irq=%d\n", irq);
/* Call the msg callback */
}
void enable_msgring_int(void *arg)
{
unsigned long mflags=0;
msgrng_access_save(&msgrng_lock, mflags);
/* enable the message ring interrupts */
msgrng_write_config((msgring_watermark_count<<24)|(IRQ_MSGRING<<16)
|(msgring_thread_mask<<8)|msgring_int_type);
msgrng_access_restore(&msgrng_lock, mflags);
}
void disable_msgring_int(void *arg)
{
unsigned long mflags=0;
uint32_t config;
msgrng_access_save(&msgrng_lock, mflags);
config = msgrng_read_config();
config &= ~0x3;
msgrng_write_config(config);
msgrng_access_restore(&msgrng_lock, mflags);
}
extern void platform_prep_smp_launch(void);
extern void msgring_process_fast_intr(void *arg);
int register_msgring_handler(int major,
void (*action)(int, int,int,int,struct msgrng_msg *, void *),
void *dev_id)
{
void *cookie; /* FIXME - use? */
if (major >= MAX_TX_STNS)
return 1;
//dbg_msg("major=%d, action=%p, dev_id=%p\n", major, action, dev_id);
mtx_lock_spin(&msgrng_lock);
tx_stn_handlers[major].action = action;
tx_stn_handlers[major].dev_id = dev_id;
mtx_unlock_spin(&msgrng_lock);
if (xlr_test_and_set(&msgring_int_enabled)) {
platform_prep_smp_launch();
cpu_establish_intr("msgring", IRQ_MSGRING,
(driver_intr_t *)msgring_process_fast_intr,
NULL, INTR_TYPE_NET|INTR_FAST, &cookie, NULL, NULL);
/* configure the msgring interrupt on cpu 0 */
enable_msgring_int(NULL);
}
return 0;
}
static void pic_init(void)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
int i=0;
int level;
dbg_msg("Initializing PIC...\n");
for(i=0; i<PIC_NUM_IRTS; i++) {
level = PIC_IRQ_IS_EDGE_TRIGGERED(i);
/* Bind all PIC irqs to cpu 0 */
xlr_write_reg(mmio, PIC_IRT_0_BASE + i, 0x01);
/* Use local scheduling and high polarity for all IRTs
* Invalidate all IRTs, by default
*/
xlr_write_reg(mmio, PIC_IRT_1_BASE + i, (level<<30)|(1<<6)|(PIC_IRQ_BASE + i));
}
}
void on_chip_init(void)
{
int i=0, j=0;
/* Set xlr_io_base to the run time value */
mtx_init(&msgrng_lock, "msgring", NULL, MTX_SPIN | MTX_RECURSE);
mtx_init(&xlr_pic_lock, "pic", NULL, MTX_SPIN);
xlr_board_info_setup();
msgring_int_enabled = 0;
xlr_msgring_config();
pic_init();
xlr_msgring_cpu_init();
for(i=0;i<MAXCPU;i++)
for(j=0;j<XLR_MAX_COUNTERS;j++)
atomic_set_int(&xlr_counters[i][j], 0);
}

328
sys/mips/rmi/pcibus.c Normal file
View File

@ -0,0 +1,328 @@
/*-
* Copyright (c) 1997, Stefan Esser <se@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/alpha/pci/pcibus.c,v 1.36 2005/01/05 20:05:52 imp Exp $");
#include "opt_isa.h"
#define __RMAN_RESOURCE_VISIBLE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/module.h>
#include <sys/proc.h>
#include <sys/bus.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/pmap.h>
#include <sys/interrupt.h>
#include <sys/sysctl.h>
#include <mips/xlr/iomap.h>
#include <mips/xlr/pic.h>
#include <mips/xlr/shared_structs.h>
#include <mips/xlr/board.h>
#include <sys/rman.h>
#include <dev/pci/pcivar.h>
#include <machine/resource.h>
#include <machine/md_var.h>
#include <machine/intr_machdep.h>
#include <mips/pci/pcibus.h>
static void bridge_pcix_ack(void *);
static void bridge_pcie_ack(void *);
static void pic_pcix_ack(void *);
static void pic_pcie_ack(void *);
extern vm_map_t kernel_map;
vm_offset_t kmem_alloc_nofault( vm_map_t map, vm_size_t size);
int
mips_pci_route_interrupt(device_t bus, device_t dev, int pin)
{
/*
* Validate requested pin number.
*/
if ((pin < 1) || (pin > 4))
return(255);
if (xlr_board_info.is_xls) {
switch (pin) {
case 1: return PIC_PCIE_LINK0_IRQ;
case 2: return PIC_PCIE_LINK1_IRQ;
case 3: return PIC_PCIE_LINK2_IRQ;
case 4: return PIC_PCIE_LINK3_IRQ;
}
} else {
if (pin == 1) {
return (16);
}
}
return(255);
}
static struct rman irq_rman, port_rman, mem_rman;
static void bridge_pcix_ack(void *arg)
{
xlr_read_reg(xlr_io_mmio(XLR_IO_PCIX_OFFSET), 0x140 >> 2);
}
static void bridge_pcie_ack(void *arg)
{
int irq = (int)arg;
uint32_t reg;
xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET);
switch (irq) {
case PIC_PCIE_LINK0_IRQ : reg = PCIE_LINK0_MSI_STATUS; break;
case PIC_PCIE_LINK1_IRQ : reg = PCIE_LINK1_MSI_STATUS; break;
case PIC_PCIE_LINK2_IRQ : reg = PCIE_LINK2_MSI_STATUS; break;
case PIC_PCIE_LINK3_IRQ : reg = PCIE_LINK3_MSI_STATUS; break;
default:
return;
}
xlr_write_reg(pcie_mmio_le, reg>>2, 0xffffffff);
}
static void pic_pcix_ack(void *none)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
mtx_lock_spin(&xlr_pic_lock);
xlr_write_reg(mmio, PIC_INT_ACK, (1 << PIC_IRT_PCIX_INDEX));
mtx_unlock_spin(&xlr_pic_lock);
}
static void pic_pcie_ack(void *arg)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
int irq = (int) arg;
mtx_lock_spin(&xlr_pic_lock);
xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
mtx_unlock_spin(&xlr_pic_lock);
}
int
mips_platform_pci_setup_intr(device_t dev, device_t child,
struct resource *irq, int flags,
driver_intr_t *intr, void *arg,
void **cookiep)
{
int level;
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
int error = 0;
int xlrirq;
error = rman_activate_resource(irq);
if (error)
return error;
if (irq->r_start != irq->r_end) {
device_printf(dev, "Interrupt allocation %lu != %lu\n",
irq->r_start, irq->r_end);
return EINVAL;
}
xlrirq = irq->r_start;
if (strcmp(device_get_name(dev),"pcib") != 0)
return 0;
if (xlr_board_info.is_xls == 0) {
mtx_lock_spin(&xlr_pic_lock);
level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_PCIX_INDEX);
xlr_write_reg(mmio, PIC_IRT_0_PCIX, 0x01);
xlr_write_reg(mmio, PIC_IRT_1_PCIX, ((1 << 31) | (level<<30)|
(1<<6)|(PIC_PCIX_IRQ)));
mtx_unlock_spin(&xlr_pic_lock);
cpu_establish_intr(device_get_name(child), PIC_PCIX_IRQ,
(driver_intr_t *)intr, (void *)arg, flags, cookiep,
pic_pcix_ack, bridge_pcix_ack);
} else {
mtx_lock_spin(&xlr_pic_lock);
xlr_write_reg(mmio, PIC_IRT_0_BASE + xlrirq - PIC_IRQ_BASE, 0x01);
xlr_write_reg(mmio, PIC_IRT_1_BASE + xlrirq - PIC_IRQ_BASE,
((1 << 31) | (1<<30) | (1<<6) | xlrirq));
mtx_unlock_spin(&xlr_pic_lock);
if (flags & INTR_FAST)
cpu_establish_intr(device_get_name(child), xlrirq,
(driver_intr_t *)intr, (void *)arg, flags, cookiep,
NULL, bridge_pcie_ack);
else
cpu_establish_intr(device_get_name(child), xlrirq,
(driver_intr_t *)intr, (void *)arg, flags, cookiep,
pic_pcie_ack, bridge_pcie_ack);
}
return bus_generic_setup_intr(dev, child, irq, flags, intr,
arg, cookiep);
}
int
mips_platform_pci_teardown_intr(device_t dev, device_t child,
struct resource *irq, void *cookie)
{
if (strcmp(device_get_name(child),"pci") == 0) {
/* if needed reprogram the pic to clear pcix related entry */
}
return bus_generic_teardown_intr(dev, child, irq, cookie);
}
void
pci_init_resources(void)
{
irq_rman.rm_start = 0;
irq_rman.rm_end = 255;
irq_rman.rm_type = RMAN_ARRAY;
irq_rman.rm_descr = "PCI Mapped Interrupts";
if (rman_init(&irq_rman)
|| rman_manage_region(&irq_rman, 0, 255))
panic("pci_init_resources irq_rman");
port_rman.rm_start = 0;
port_rman.rm_end = ~0u;
port_rman.rm_type = RMAN_ARRAY;
port_rman.rm_descr = "I/O ports";
if (rman_init(&port_rman)
|| rman_manage_region(&port_rman, 0x10000000, 0x1fffffff))
panic("pci_init_resources port_rman");
mem_rman.rm_start = 0;
mem_rman.rm_end = ~0u;
mem_rman.rm_type = RMAN_ARRAY;
mem_rman.rm_descr = "I/O memory";
if (rman_init(&mem_rman)
|| rman_manage_region(&mem_rman, 0xd0000000, 0xdfffffff))
panic("pci_init_resources mem_rman");
}
struct resource *
xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct rman *rm;
struct resource *rv;
vm_offset_t va_start, va;
int needactivate = flags & RF_ACTIVE;
#if 0
device_printf(bus, "xlr_pci_alloc_resource : child %s, type %d, start %lx end %lx, count %lx, flags %x\n",
device_get_nameunit(child), type, start, end, count, flags);
#endif
switch (type) {
case SYS_RES_IRQ:
rm = &irq_rman;
break;
case SYS_RES_IOPORT:
rm = &port_rman;
break;
case SYS_RES_MEMORY:
rm = &mem_rman;
break;
default:
return 0;
}
rv = rman_reserve_resource(rm, start, end, count, flags, child);
if (rv == 0)
return 0;
rman_set_bustag(rv, MIPS_BUS_SPACE_PCI);
rman_set_rid(rv, *rid);
if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
if ((start + count) > (2 << 28)) {
va_start = kmem_alloc_nofault(kernel_map, count);
}
va = pmap_map_uncached(&va_start, start, start + count);
rman_set_bushandle(rv, va);
/* bushandle is same as virtual addr */
rman_set_virtual(rv, (void *)va);
rman_set_bustag(rv, MIPS_BUS_SPACE_PCI);
}
if (needactivate) {
if (bus_activate_resource(child, type, *rid, rv)) {
rman_release_resource(rv);
return (NULL);
}
}
return rv;
}
int
pci_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
return (rman_activate_resource(r));
}
int
pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
return (rman_deactivate_resource(r));
}
int
pci_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
return (rman_release_resource(r));
}
struct rman *
pci_get_rman(device_t dev, int type)
{
switch (type) {
case SYS_RES_IOPORT:
return &port_rman;
case SYS_RES_MEMORY:
return &mem_rman;
case SYS_RES_IRQ:
return &irq_rman;
}
return 0;
}

49
sys/mips/rmi/pcibus.h Normal file
View File

@ -0,0 +1,49 @@
/*-
* Copyright (c) 1998 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/alpha/pci/pcibus.h,v 1.5 2002/02/28 18:18:41 gallatin Exp $
*/
#define DEFAULT_PCI_CONFIG_BASE 0x18000000
#define MSI_MIPS_ADDR_BASE 0xfee00000
#define PCIE_LINK0_MSI_STATUS 0x90
#define PCIE_LINK1_MSI_STATUS 0x94
#define PCIE_LINK2_MSI_STATUS 0x190
#define PCIE_LINK3_MSI_STATUS 0x194
void pci_init_resources(void);
struct resource *xlr_pci_alloc_resource(device_t bus, device_t child,
int type, int *rid,
u_long start, u_long end, u_long count,
u_int flags);
int pci_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r);
int pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r);
int pci_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *r);
struct rman *pci_get_rman(device_t dev, int type);

168
sys/mips/rmi/perfmon.h Normal file
View File

@ -0,0 +1,168 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#ifndef PERFMON_H
#define PERFMON_H
#include <mips/xlr/perfmon_xlrconfig.h>
/*
* category events reported by the perfmon library
*/
enum event_category_t { PERF_CP0_COUNTER=1, PERF_CP2_CREDITS, PERF_L2_COUNTER,
PERF_SBC_COUNTER, PERF_SBC_CREDITS, PERF_GMAC0_COUNTER, PERF_GMAC1_COUNTER,
PERF_GMAC2_COUNTER, PERF_GMAC_STAT_COM, PERF_GMAC_STAT_TX,
PERF_GMAC_STAT_RX, PERF_DRAM_COUNTER, PERF_PARAMETER_CONF=127};
enum perf_param_t { PERF_CPU_SAMPLING_INTERVAL, PERF_SYS_SAMPLING_INTERVAL, PERF_CC_SAMPLE_RATE, PERF_CP0_FLAGS};
#define CPO_EVENTS_TEMPLATE 0x06 /* enable kernel and user events */
#define PERFMON_ACTIVE_MAGIC 0xc001
#define PERFMON_ENABLED_MAGIC 0xb007
#define PERFMON_INITIAL_GENERATION 0x0101
#define PERFMON_SERVER_PORT 7007
enum system_bridge_credits_t {PCIX_CREDITS, HT_CREDITS, GIO_CREDITS, OTHER_CREDITS};
struct perf_config_data {
uint16_t magic; /* monitor start when this is initialized */
uint16_t generation; /* incremented when the config changes */
uint16_t flags;
uint16_t cc_sample_rate; /* rate at which credit counters are sampled
relative to sampling_rate */
uint32_t sampling_rate; /* rate at which events are sampled */
uint32_t cc_register_mask; /* credit counters registers to be sampled */
uint64_t events[NTHREADS]; /* events bitmap for each thread */
};
struct perf_sample {
uint32_t counter;
uint32_t timestamp;
uint32_t sample_tag;
uint32_t duration;
};
struct sample_q {
int32_t head, tail;
struct perf_sample samples[PERF_SAMPLE_BUFSZ];
uint32_t overflows;
};
struct perf_area {
struct perf_config_data perf_config;
struct sample_q sample_fifo;
};
/*
* We have a shared location to keep a global tick counter for all the
* CPUS - TODO is this optimal? effect on cache?
*/
extern uint32_t *xlr_perfmon_timer_loc;
#define PERFMON_TIMESTAMP_LOC (xlr_perfmon_timer_loc)
static __inline__ uint32_t perfmon_timestamp_get(void)
{
return *PERFMON_TIMESTAMP_LOC;
}
static __inline__ void perfmon_timestamp_set(uint32_t val)
{
*PERFMON_TIMESTAMP_LOC = val;
}
static __inline__ void perfmon_timestamp_incr(int val)
{
(*PERFMON_TIMESTAMP_LOC) += val;
}
static __inline__ void send_sample_gts(uint32_t tag, uint32_t value, uint32_t td)
{
xlr_send_sample(tag, value, perfmon_timestamp_get(), td);
}
/*
* Simple FIFO, one producer - one consumer - circlar queue - no locking
*/
static __inline__ void init_fifo(struct sample_q *q)
{
q->head = q->tail = 0;
}
static __inline__ void put_sample(struct sample_q *q, uint32_t sample_tag, uint32_t counter,
uint32_t duration)
{
uint32_t timestamp = perfmon_timestamp_get();
int new_tail = (q->tail + 1) % PERF_SAMPLE_BUFSZ;
if (q->head == new_tail) {
q->overflows++;
return;
}
q->samples[new_tail].sample_tag = sample_tag;
q->samples[new_tail].counter = counter;
q->samples[new_tail].timestamp = timestamp;
q->samples[new_tail].duration = duration;
q->tail = new_tail;
}
static __inline__ int get_sample(struct sample_q *q, uint32_t *sample_tag, uint32_t *counter,
uint32_t *timestamp, uint32_t *duration)
{
int head = q->head;
if (head == q->tail)
return 0;
*sample_tag = q->samples[head].sample_tag;
*counter = q->samples[head].counter;
*timestamp = q->samples[head].timestamp;
*duration = q->samples[head].duration;
q->head = (head+1) % PERF_SAMPLE_BUFSZ;
return 1;
}
static __inline__ void clear_queue(struct sample_q *q)
{
q->head = q->tail;
}
void xlr_perfmon_init_cpu(void *);
void xlr_perfmon_sampler(void *);
void log_active_core(int core);
int get_start_generation(void);
void xlr_perfmon_clockhandler (void);
extern int xlr_perfmon_started;
#endif /* PERFMON_H */

162
sys/mips/rmi/perfmon_kern.c Normal file
View File

@ -0,0 +1,162 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/pcpu.h>
#include <sys/proc.h>
#include <sys/smp.h>
#include <sys/sysctl.h>
#include <machine/smp.h>
#include <mips/xlr/perfmon.h>
#include <mips/xlr/pic.h>
#include <sys/mutex.h>
#include <mips/xlr/clock.h>
int xlr_perfmon_started = 0;
struct perf_area *xlr_shared_config_area = NULL;
uint32_t *xlr_perfmon_timer_loc;
uint32_t *xlr_cpu_sampling_interval;
uint32_t xlr_perfmon_kernel_version = 1; /* Future use */
uint32_t xlr_perfmon_ticks;
extern int mips_cpu_online_mask;
extern uint32_t cpu_ltop_map[MAXCPU];
#ifdef SMP
static __inline__ void pic_send_perfmon_ipi(int cpu)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
int tid, pid;
uint32_t ipi;
tid = cpu & 0x3;
pid = (cpu >> 2) & 0x7;
ipi = (pid << 20) | (tid << 16) | IPI_PERFMON;
mtx_lock_spin(&xlr_pic_lock);
xlr_write_reg(mmio, PIC_IPI, ipi);
mtx_unlock_spin(&xlr_pic_lock);
}
#endif
void
xlr_perfmon_clockhandler(void)
{
#ifdef SMP
int cpu;
int i;
#endif
if (xlr_perfmon_ticks++ >= (*xlr_cpu_sampling_interval)/(XLR_PIC_HZ/(hz * 1024))) {
/* update timer */
*xlr_perfmon_timer_loc += *xlr_cpu_sampling_interval;
xlr_perfmon_ticks = 0;
xlr_perfmon_sampler(NULL);
#ifdef SMP
for (i=0; i<NCPUS; i = i+NTHREADS) { /* oly thread 0 */
cpu = cpu_ltop_map[i];
if ((mips_cpu_online_mask & (1 << i)) &&
xlr_shared_config_area[cpu/NTHREADS].perf_config.magic ==
PERFMON_ACTIVE_MAGIC)
pic_send_perfmon_ipi(cpu);
}
#endif
}
}
static void
xlr_perfmon_start(void)
{
size_t size;
size = (NCORES * sizeof(*xlr_shared_config_area)) +
sizeof(*xlr_perfmon_timer_loc) +
sizeof(*xlr_cpu_sampling_interval);
xlr_shared_config_area = malloc(size, M_TEMP, M_WAITOK);
if (!xlr_shared_config_area) {
/* ERROR */
return;
}
xlr_perfmon_timer_loc = (uint32_t *)(xlr_shared_config_area + NCORES);
xlr_cpu_sampling_interval = (uint32_t *)(xlr_perfmon_timer_loc +1);
*xlr_cpu_sampling_interval = DEFAULT_CPU_SAMPLING_INTERVAL;
*xlr_perfmon_timer_loc = 0;
xlr_perfmon_ticks = 0;
xlr_perfmon_init_cpu(NULL);
#ifdef SMP
smp_call_function(xlr_perfmon_init_cpu, NULL,
PCPU_GET(other_cpus) & 0x11111111);
#endif
xlr_perfmon_started = 1;
}
static void
xlr_perfmon_stop(void)
{
xlr_perfmon_started = 0;
free(xlr_shared_config_area, M_TEMP);
xlr_shared_config_area = NULL;
}
static int
sysctl_xlr_perfmon_start_stop(SYSCTL_HANDLER_ARGS)
{
int error, val = xlr_perfmon_started;
error = sysctl_handle_int(oidp, &val, 0, req);
if (error != 0 || req->newptr == NULL)
return (error);
if (!xlr_perfmon_started && val != 0)
xlr_perfmon_start();
else if (xlr_perfmon_started && val == 0)
xlr_perfmon_stop();
return (0);
}
SYSCTL_NODE(_debug, OID_AUTO, xlrperf, CTLFLAG_RW, NULL, "XLR PERF Nodes");
SYSCTL_PROC(_debug_xlrperf, OID_AUTO, start, CTLTYPE_INT | CTLFLAG_RW,
&xlr_perfmon_started, 0, sysctl_xlr_perfmon_start_stop, "I", "set/unset to start/stop "
"performance monitoring");

View File

@ -0,0 +1,299 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/smp.h>
#include <sys/pcpu.h>
#include <mips/xlr/xlrconfig.h>
#include <mips/xlr/perfmon_xlrconfig.h>
#include <mips/xlr/perfmon.h>
#include <mips/xlr/perfmon_utils.h>
#include <mips/xlr/pic.h>
#include <mips/xlr/msgring.h>
#define CC_SAMPLE (PERF_CP2_CREDITS <<24)
#define CC_REG0 16
#define CC_REG1 17
#define CC_REG2 18
#define CC_REG3 19
#define CC_REG4 20
#define CC_REG5 21
#define CC_REG6 22
#define CC_REG7 23
#define CC_REG8 24
#define CC_REG9 25
#define CC_REG10 26
#define CC_REG11 27
#define CC_REG12 28
#define CC_REG13 29
#define CC_REG14 30
#define CC_REG15 31
extern uint32_t cpu_ltop_map[MAXCPU];
extern struct perf_area *xlr_shared_config_area;
static __inline__ uint32_t make_cpu_tag(uint32_t val)
{
return PERF_CP0_COUNTER<<24 | (val & 0xffff);
}
static __inline__ uint32_t make_cp0_perf_control(uint32_t flags, uint32_t thread, uint32_t event)
{
return (flags & 0x1f) | (thread & 0x03)<<11 | (event & 0x3f)<<5 | 0x01;
}
static __inline__ uint32_t cp0_perf_control_get_thread(uint32_t control_word)
{
return (control_word & 0x1800)>>11;
}
static __inline__ uint32_t cp0_perf_control_get_event(uint32_t control_word)
{
return (control_word & 0x7e0)>>5;
}
static __inline__ uint32_t read_pic_6_timer_count(void)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
/* PIC counts down, convert it to count up */
return 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0);
}
static uint32_t get_num_events(const uint64_t *events)
{
int total = 0;
int thread;
for(thread = 0; thread<NTHREADS; thread++) {
if (events[thread] == 0)
continue;
total += get_set_bit_count64(events[thread]);
}
return total;
}
static uint32_t get_first_control_word(uint32_t flags, const uint64_t *events)
{
int thread, event;
for(thread = 0; thread<NTHREADS; thread++) {
if (events[thread] != 0) break;
}
if(thread == NTHREADS)
return -1;
event = find_first_set_bit64(events[thread]);
return make_cp0_perf_control(flags, thread, event);
}
static uint32_t get_next_control_word(uint32_t current_control_word, const uint64_t *events)
{
int thread = cp0_perf_control_get_thread(current_control_word);
int event = cp0_perf_control_get_event(current_control_word);
int i;
event = find_next_set_bit64(events[thread], event);
for(i = 0; event == -1 && i<NTHREADS; i++) {
thread = (thread + 1) % NTHREADS;
if (events[thread] == 0)
continue;
event = find_first_set_bit64(events[thread]);
}
ASSERT(event != -1);
return make_cp0_perf_control(current_control_word, thread, event);
}
/* Global state per core */
#define MY_CORE_NUM (cpu_ltop_map[PCPU_GET(cpuid)]/NTHREADS)
#define my_perf_area (&(xlr_shared_config_area[MY_CORE_NUM]))
static int num_events_array[NCORES];
static uint32_t saved_timestamp_array[NCORES];
static struct perf_config_data saved_config_array[NCORES];
static int cc_sample_array[NCORES];
#define num_events (num_events_array[MY_CORE_NUM])
#define saved_timestamp (saved_timestamp_array[MY_CORE_NUM])
#define saved_config (saved_config_array[MY_CORE_NUM])
#define cc_sample (cc_sample_array[MY_CORE_NUM])
static void do_sample_cc_registers(struct sample_q *q, uint32_t mask)
{
unsigned long flags;
DPRINT("Sample CC registers %x", mask);
msgrng_flags_save(flags);
if (mask & 0x00000001) put_sample(q, CC_SAMPLE + 0, read_cc_registers_0123(CC_REG0), 0);
if (mask & 0x00000002) put_sample(q, CC_SAMPLE + 1, read_cc_registers_4567(CC_REG0), 0);
if (mask & 0x00000004) put_sample(q, CC_SAMPLE + 2, read_cc_registers_0123(CC_REG1), 0);
if (mask & 0x00000008) put_sample(q, CC_SAMPLE + 3, read_cc_registers_4567(CC_REG1), 0);
if (mask & 0x00000010) put_sample(q, CC_SAMPLE + 4, read_cc_registers_0123(CC_REG2), 0);
if (mask & 0x00000020) put_sample(q, CC_SAMPLE + 5, read_cc_registers_4567(CC_REG2), 0);
if (mask & 0x00000040) put_sample(q, CC_SAMPLE + 6, read_cc_registers_0123(CC_REG3), 0);
if (mask & 0x00000080) put_sample(q, CC_SAMPLE + 7, read_cc_registers_4567(CC_REG3), 0);
if (mask & 0x00000100) put_sample(q, CC_SAMPLE + 8, read_cc_registers_0123(CC_REG4), 0);
if (mask & 0x00000200) put_sample(q, CC_SAMPLE + 9, read_cc_registers_4567(CC_REG4), 0);
if (mask & 0x00000400) put_sample(q, CC_SAMPLE + 10, read_cc_registers_0123(CC_REG5), 0);
if (mask & 0x00000800) put_sample(q, CC_SAMPLE + 11, read_cc_registers_4567(CC_REG5), 0);
if (mask & 0x00001000) put_sample(q, CC_SAMPLE + 12, read_cc_registers_0123(CC_REG6), 0);
if (mask & 0x00002000) put_sample(q, CC_SAMPLE + 13, read_cc_registers_4567(CC_REG6), 0);
if (mask & 0x00004000) put_sample(q, CC_SAMPLE + 14, read_cc_registers_0123(CC_REG7), 0);
if (mask & 0x00008000) put_sample(q, CC_SAMPLE + 15, read_cc_registers_4567(CC_REG7), 0);
if (mask & 0x00010000) put_sample(q, CC_SAMPLE + 16, read_cc_registers_0123(CC_REG8), 0);
if (mask & 0x00020000) put_sample(q, CC_SAMPLE + 17, read_cc_registers_4567(CC_REG8), 0);
if (mask & 0x00040000) put_sample(q, CC_SAMPLE + 18, read_cc_registers_0123(CC_REG9), 0);
if (mask & 0x00080000) put_sample(q, CC_SAMPLE + 19, read_cc_registers_4567(CC_REG9), 0);
if (mask & 0x00100000) put_sample(q, CC_SAMPLE + 20, read_cc_registers_0123(CC_REG10), 0);
if (mask & 0x00200000) put_sample(q, CC_SAMPLE + 21, read_cc_registers_4567(CC_REG10), 0);
if (mask & 0x00400000) put_sample(q, CC_SAMPLE + 22, read_cc_registers_0123(CC_REG11), 0);
if (mask & 0x00800000) put_sample(q, CC_SAMPLE + 23, read_cc_registers_4567(CC_REG11), 0);
if (mask & 0x01000000) put_sample(q, CC_SAMPLE + 24, read_cc_registers_0123(CC_REG12), 0);
if (mask & 0x02000000) put_sample(q, CC_SAMPLE + 24, read_cc_registers_4567(CC_REG12), 0);
if (mask & 0x04000000) put_sample(q, CC_SAMPLE + 26, read_cc_registers_0123(CC_REG13), 0);
if (mask & 0x08000000) put_sample(q, CC_SAMPLE + 27, read_cc_registers_4567(CC_REG13), 0);
if (mask & 0x10000000) put_sample(q, CC_SAMPLE + 28, read_cc_registers_0123(CC_REG14), 0);
if (mask & 0x20000000) put_sample(q, CC_SAMPLE + 29, read_cc_registers_4567(CC_REG14), 0);
if (mask & 0x40000000) put_sample(q, CC_SAMPLE + 30, read_cc_registers_0123(CC_REG15), 0);
if (mask & 0x80000000) put_sample(q, CC_SAMPLE + 31, read_cc_registers_4567(CC_REG15), 0);
msgrng_flags_restore(flags);
}
static void reconfigure(void)
{
uint32_t cntr_cntrl;
saved_config = my_perf_area->perf_config;
num_events = get_num_events(saved_config.events);
cc_sample = saved_config.cc_sample_rate;
DPRINT("%d - reconfigure num_events = %d, events = %llx,%llx,%llx,%llx\n",
processor_id(), num_events, saved_config.events[0],
saved_config.events[1],saved_config.events[2],saved_config.events[3] );
if (num_events == 0)
return;
cntr_cntrl = get_first_control_word(saved_config.flags, saved_config.events);
write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0, cntr_cntrl);
write_c0_register(CP0_PERF_COUNTER, PERFCNTR0, 0); /* reset count */
if (num_events > 1) {
cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events);
write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1, cntr_cntrl);
write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */
}
saved_timestamp = read_pic_6_timer_count();
}
int xlr_perfmon_no_event_count = 0;
int xlr_perfmon_sample_count;
/* timer callback routine */
void xlr_perfmon_sampler(void *dummy)
{
uint32_t current_ts;
uint32_t cntr_cntrl=0;
/* xlr_ack_interrupt(XLR_PERFMON_IPI_VECTOR); */
if (my_perf_area->perf_config.magic != PERFMON_ACTIVE_MAGIC)
return;
/*
* If there has been a change in configuation, update the configuration
*/
if (saved_config.generation != my_perf_area->perf_config.generation) {
reconfigure();
return;
}
/* credit counter samples if reqd */
if(saved_config.cc_register_mask && --cc_sample == 0) {
cc_sample = saved_config.cc_sample_rate;
do_sample_cc_registers(&my_perf_area->sample_fifo,
my_perf_area->perf_config.cc_register_mask);
}
if (num_events == 0) {
xlr_perfmon_no_event_count++;
return;
}
/* put samples in the queue */
current_ts = read_pic_6_timer_count();
cntr_cntrl = read_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0);
put_sample(&my_perf_area->sample_fifo, make_cpu_tag(cntr_cntrl),
read_c0_register(CP0_PERF_COUNTER, PERFCNTR0), current_ts - saved_timestamp);
xlr_perfmon_sample_count++;
write_c0_register(CP0_PERF_COUNTER, PERFCNTR0, 0); /* reset count */
if(num_events > 1) {
cntr_cntrl = read_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1);
put_sample(&my_perf_area->sample_fifo, make_cpu_tag(cntr_cntrl),
read_c0_register(CP0_PERF_COUNTER, PERFCNTR1), current_ts - saved_timestamp);
xlr_perfmon_sample_count++;
write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */
if(num_events > 2) {
/* multiplex events */
cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events);
write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0, cntr_cntrl);
cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events);
write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1, cntr_cntrl);
}
}
saved_timestamp = read_pic_6_timer_count();
}
/*
* Initializes time to gather CPU performance counters and credit counters
*/
void xlr_perfmon_init_cpu(void *dummy)
{
int processor = cpu_ltop_map[PCPU_GET(cpuid)];
/* run on just one thread per core */
if(processor % 4)
return;
DPRINT("%d : configure with %p", processor, my_perf_area);
memset(my_perf_area, 0, sizeof(*my_perf_area));
init_fifo(&my_perf_area->sample_fifo);
my_perf_area->perf_config.magic = PERFMON_ENABLED_MAGIC;
my_perf_area->perf_config.generation = PERFMON_INITIAL_GENERATION;
DPRINT("%d : Initialize", processor);
return ;
}

View File

@ -0,0 +1,113 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#ifndef UTILS_H
#define UTILS_H
#include <machine/stdarg.h> /* variable args */
/* TODO optimize of mips, even i & (i-1) is better */
static int __inline__ get_set_bit_count64(uint64_t value)
{
int i, result=0;
for(i=0; i<sizeof(value) *8; i++)
if(value & (1ULL<<i)) result++;
return result;
}
static int __inline__ find_first_set_bit64(uint64_t value)
{
int i;
for(i=0; i<sizeof(value) *8; i++)
if(value & (1ULL<<i)) return i;
return -1;
}
static int __inline__ find_next_set_bit64(uint64_t value, int pos)
{
int i;
for(i=pos+1; i<sizeof(value) *8; i++)
if(value & (1ULL<<i)) return i;
return -1;
}
/** --- **/
static int __inline__ get_set_bit_count(uint32_t value)
{
int i, result=0;
for(i=0; i<sizeof(value) *8; i++)
if(value & (1U<<i)) result++;
return result;
}
static int __inline__ find_first_set_bit(uint32_t value)
{
int i;
for(i=0; i<sizeof(value) *8; i++)
if(value & (1U<<i)) return i;
return -1;
}
static int __inline__ find_next_set_bit(uint32_t value, int pos)
{
int i;
for(i=pos+1; i<sizeof(value) *8; i++)
if(value & (1U<<i)) return i;
return -1;
}
#ifdef DEBUG
void abort();
#define DPUTC(c) (putchar(c) && fflush(stdout))
#define DPRINT(fmt, ...) printf(fmt "\n", __VA_ARGS__)
#define ASSERT(x) ((x) || ({ printf("%s failed at (%s:%d)", #x, __FILE__, __LINE__) ; abort(); 0; }) )
#else
#define DPUTC(c)
#define DPRINT(fmt, ...)
#define ASSERT(x)
#endif
void xlr_send_sample(uint32_t tag, uint32_t value, uint32_t ts, uint32_t td);
#endif

View File

@ -0,0 +1,156 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#ifdef XLR_PERFMON
#ifndef XLRCONFIG_PERFMON_H
#define XLRCONFIG_PERFMON_H
#include <mips/xlr/perfmon_utils.h> /* for DPRINT */
#define NCPUS 32
#define NCORES 8
#define NTHREADS 4
#define PERF_SAMPLE_BUFSZ 32
/*select timeout is 512*1024 microsecs */
#define DEFAULT_SYS_SAMPLING_INTERVAL (512*1024)
/* default timer value programmed to PIC is 10*1024*1024 */
#define DEFAULT_CPU_SAMPLING_INTERVAL (10*1024)
#define DEFAULT_CC_SAMPLE_RATE 16
#define DEFAULT_CP0_FLAGS 0x0A
#define NUM_L2_BANKS 8
#define NUM_DRAM_BANKS 4
/* CP0 register for timestamp */
#define CP0_COUNT 9
#define CP0_EIRR_REG 9
#define CP0_EIRR_SEL 6
#define CP0_EIMR_REG 9
#define CP0_EIMR_SEL 7
/* CP0 register for perf counters */
#define CP0_PERF_COUNTER 25
/* selector values */
#define PERFCNTRCTL0 0
#define PERFCNTR0 1
#define PERFCNTRCTL1 2
#define PERFCNTR1 3
#define XLR_IO_PIC_OFFSET 0x08000
#define PIC_SYS_TIMER_0_BASE 0x120
#define PIC_SYS_TIMER_NUM_6 6
/* CP2 registers for reading credit counters */
#define CC_REG0 16
#define read_c0_register(reg, sel) \
({ unsigned int __rv; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set mips32\n\t" \
"mfc0\t%0,$%1,%2\n\t" \
".set\tpop" \
: "=r" (__rv) : "i" (reg), "i" (sel) ); \
__rv;})
#define write_c0_register(reg, sel, value) \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set mips32\n\t" \
"mtc0\t%0,$%1,%2\n\t" \
".set\tpop" \
: : "r" (value), "i" (reg), "i" (sel) );
#define read_c2_register(reg, sel) \
({ unsigned int __rv; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set mips32\n\t" \
"mfc0\t%0,$%1,%2\n\t" \
".set\tpop" \
: "=r" (__rv) : "i"(reg), "i" (sel) ); \
__rv;})
/*
* We have 128 registers in C2 credit counters, reading them one at
* a time using bitmap will take a lot of code, so we have two functions
* to read registers sel0-3 and sel 4-7 into one 32 bit word.
*/
#define read_cc_registers_0123(reg) \
({ \
unsigned int __rv; \
\
__asm__ __volatile__( \
".set push\n\t" \
".set mips32\n\t" \
".set noreorder\n\t" \
"mfc2 %0, $%1, 0\n\t" \
"mfc2 $8, $%1, 1\n\t" \
"sll %0, %0, 8\n\t" \
"or %0, %0, $8\n\t" \
"mfc2 $8, $%1, 2\n\t" \
"sll %0, %0, 8\n\t" \
"or %0, %0, $8\n\t" \
"mfc2 $8, $%1, 3\n\t" \
"sll %0, %0, 8\n\t" \
"or %0, %0, $8\n\t" \
".set pop" \
: "=r" (__rv) : "i"(reg) : "$8"); \
\
__rv; \
})
#define read_cc_registers_4567(reg) \
({ \
unsigned int __rv; \
\
__asm__ __volatile__( \
".set push\n\t" \
".set mips32\n\t" \
".set noreorder\n\t" \
"mfc2 %0, $%1, 4\n\t" \
"mfc2 $8, $%1, 5\n\t" \
"sll %0, %0, 8\n\t" \
"or %0, %0, $8\n\t" \
"mfc2 $8, $%1, 6\n\t" \
"sll %0, %0, 8\n\t" \
"or %0, %0, $8\n\t" \
"mfc2 $8, $%1, 7\n\t" \
"sll %0, %0, 8\n\t" \
"or %0, %0, $8\n\t" \
".set pop" \
: "=r" (__rv) :"i"(reg) : "$8"); \
\
__rv; \
})
#endif
#endif

257
sys/mips/rmi/pic.h Normal file
View File

@ -0,0 +1,257 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#ifndef _RMI_PIC_H_
#define _RMI_PIC_H_
#include <sys/lock.h>
#include <sys/mutex.h>
#include <mips/xlr/iomap.h>
#define PIC_IRT_WD_INDEX 0
#define PIC_IRT_TIMER_0_INDEX 1
#define PIC_IRT_TIMER_1_INDEX 2
#define PIC_IRT_TIMER_2_INDEX 3
#define PIC_IRT_TIMER_3_INDEX 4
#define PIC_IRT_TIMER_4_INDEX 5
#define PIC_IRT_TIMER_5_INDEX 6
#define PIC_IRT_TIMER_6_INDEX 7
#define PIC_IRT_TIMER_7_INDEX 8
#define PIC_IRT_CLOCK_INDEX PIC_IRT_TIMER_7_INDEX
#define PIC_IRT_UART_0_INDEX 9
#define PIC_IRT_UART_1_INDEX 10
#define PIC_IRT_I2C_0_INDEX 11
#define PIC_IRT_I2C_1_INDEX 12
#define PIC_IRT_PCMCIA_INDEX 13
#define PIC_IRT_GPIO_INDEX 14
#define PIC_IRT_HYPER_INDEX 15
#define PIC_IRT_PCIX_INDEX 16
#define PIC_IRT_GMAC0_INDEX 17
#define PIC_IRT_GMAC1_INDEX 18
#define PIC_IRT_GMAC2_INDEX 19
#define PIC_IRT_GMAC3_INDEX 20
#define PIC_IRT_XGS0_INDEX 21
#define PIC_IRT_XGS1_INDEX 22
#define PIC_IRT_HYPER_FATAL_INDEX 23
#define PIC_IRT_PCIX_FATAL_INDEX 24
#define PIC_IRT_BRIDGE_AERR_INDEX 25
#define PIC_IRT_BRIDGE_BERR_INDEX 26
#define PIC_IRT_BRIDGE_TB_INDEX 27
#define PIC_IRT_BRIDGE_AERR_NMI_INDEX 28
/* numbering for XLS */
#define PIC_IRT_BRIDGE_ERR_INDEX 25
#define PIC_IRT_PCIE_LINK0_INDEX 26
#define PIC_IRT_PCIE_LINK1_INDEX 27
#define PIC_IRT_PCIE_LINK2_INDEX 23
#define PIC_IRT_PCIE_LINK3_INDEX 24
#define PIC_IRT_PCIE_INT_INDEX 28
#define PIC_IRT_PCIE_FATAL_INDEX 29
#define PIC_IRT_GPIO_B_INDEX 30
#define PIC_IRT_USB_INDEX 31
#define PIC_NUM_IRTS 32
#define PIC_SYS_TIMER_MAXVAL_0_BASE 0x100
#define PIC_SYS_TIMER_MAXVAL_1_BASE 0x110
#define PIC_SYS_TIMER_0_BASE 0x120
#define PIC_SYS_TIMER_1_BASE 0x130
#define PIC_CLOCK_TIMER 7
#define PIC_CTRL 0x00
#define PIC_IPI 0x04
#define PIC_INT_ACK 0x06
#define WD_MAX_VAL_0 0x08
#define WD_MAX_VAL_1 0x09
#define WD_MASK_0 0x0a
#define WD_MASK_1 0x0b
#define WD_HEARBEAT_0 0x0c
#define WD_HEARBEAT_1 0x0d
#define PIC_IRT_0_BASE 0x40
#define PIC_IRT_1_BASE 0x80
#define PIC_IRT_0_WD (PIC_IRT_0_BASE + PIC_IRT_WD_INDEX)
#define PIC_IRT_1_WD (PIC_IRT_1_BASE + PIC_IRT_WD_INDEX)
#define PIC_IRT_0_TIMER_0 (PIC_IRT_0_BASE + PIC_IRT_TIMER_0_INDEX)
#define PIC_IRT_1_TIMER_0 (PIC_IRT_1_BASE + PIC_IRT_TIMER_0_INDEX)
#define PIC_IRT_0_TIMER_1 (PIC_IRT_0_BASE + PIC_IRT_TIMER_1_INDEX)
#define PIC_IRT_1_TIMER_1 (PIC_IRT_1_BASE + PIC_IRT_TIMER_1_INDEX)
#define PIC_IRT_0_TIMER_2 (PIC_IRT_0_BASE + PIC_IRT_TIMER_2_INDEX)
#define PIC_IRT_1_TIMER_2 (PIC_IRT_1_BASE + PIC_IRT_TIMER_2_INDEX)
#define PIC_IRT_0_TIMER_3 (PIC_IRT_0_BASE + PIC_IRT_TIMER_3_INDEX)
#define PIC_IRT_1_TIMER_3 (PIC_IRT_1_BASE + PIC_IRT_TIMER_3_INDEX)
#define PIC_IRT_0_TIMER_4 (PIC_IRT_0_BASE + PIC_IRT_TIMER_4_INDEX)
#define PIC_IRT_1_TIMER_4 (PIC_IRT_1_BASE + PIC_IRT_TIMER_4_INDEX)
#define PIC_IRT_0_TIMER_5 (PIC_IRT_0_BASE + PIC_IRT_TIMER_5_INDEX)
#define PIC_IRT_1_TIMER_5 (PIC_IRT_1_BASE + PIC_IRT_TIMER_5_INDEX)
#define PIC_IRT_0_TIMER_6 (PIC_IRT_0_BASE + PIC_IRT_TIMER_6_INDEX)
#define PIC_IRT_1_TIMER_6 (PIC_IRT_1_BASE + PIC_IRT_TIMER_6_INDEX)
#define PIC_IRT_0_TIMER_7 (PIC_IRT_0_BASE + PIC_IRT_TIMER_7_INDEX)
#define PIC_IRT_1_TIMER_7 (PIC_IRT_1_BASE + PIC_IRT_TIMER_7_INDEX)
#define PIC_IRT_0_CLOCK (PIC_IRT_0_TIMER_7)
#define PIC_IRT_1_CLOCK (PIC_IRT_1_TIMER_7)
#define PIC_IRT_0_UART_0 (PIC_IRT_0_BASE + PIC_IRT_UART_0_INDEX)
#define PIC_IRT_1_UART_0 (PIC_IRT_1_BASE + PIC_IRT_UART_0_INDEX)
#define PIC_IRT_0_UART_1 (PIC_IRT_0_BASE + PIC_IRT_UART_1_INDEX)
#define PIC_IRT_1_UART_1 (PIC_IRT_1_BASE + PIC_IRT_UART_1_INDEX)
#define PIC_IRT_0_I2C_0 (PIC_IRT_0_BASE + PIC_IRT_I2C_0_INDEX)
#define PIC_IRT_1_I2C_0 (PIC_IRT_1_BASE + PIC_IRT_I2C_0_INDEX)
#define PIC_IRT_0_I2C_1 (PIC_IRT_0_BASE + PIC_IRT_I2C_1_INDEX)
#define PIC_IRT_1_I2C_1 (PIC_IRT_1_BASE + PIC_IRT_I2C_1_INDEX)
#define PIC_IRT_0_HYPER (PIC_IRT_0_BASE + PIC_IRT_HYPER_INDEX)
#define PIC_IRT_1_HYPER (PIC_IRT_1_BASE + PIC_IRT_HYPER_INDEX)
#define PIC_IRT_0_PCIX (PIC_IRT_0_BASE + PIC_IRT_PCIX_INDEX)
#define PIC_IRT_1_PCIX (PIC_IRT_1_BASE + PIC_IRT_PCIX_INDEX)
#define PIC_TIMER_0_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 0)
#define PIC_TIMER_0_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 0)
#define PIC_TIMER_0_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 0)
#define PIC_TIMER_0_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 0)
#define PIC_TIMER_6_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 6)
#define PIC_TIMER_6_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 6)
#define PIC_TIMER_6_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 6)
#define PIC_TIMER_6_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 6)
#define PIC_TIMER_7_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 7)
#define PIC_TIMER_7_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 7)
#define PIC_TIMER_7_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 7)
#define PIC_TIMER_7_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 7)
#define PIC_IRQ_BASE 8
#define PIC_IRT_FIRST_IRQ PIC_IRQ_BASE
#define PIC_WD_IRQ (PIC_IRQ_BASE + PIC_IRT_WD_INDEX)
#define PIC_TIMER_0_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_0_INDEX)
#define PIC_TIMER_1_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_1_INDEX)
#define PIC_TIMER_2_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_2_INDEX)
#define PIC_TIMER_3_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_3_INDEX)
#define PIC_TIMER_4_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_4_INDEX)
#define PIC_TIMER_5_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_5_INDEX)
#define PIC_TIMER_6_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_6_INDEX)
#define PIC_TIMER_7_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_7_INDEX)
#define PIC_CLOCK_IRQ (PIC_TIMER_7_IRQ)
#define PIC_UART_0_IRQ (PIC_IRQ_BASE + PIC_IRT_UART_0_INDEX)
#define PIC_UART_1_IRQ (PIC_IRQ_BASE + PIC_IRT_UART_1_INDEX)
#define PIC_I2C_0_IRQ (PIC_IRQ_BASE + PIC_IRT_I2C_0_INDEX)
#define PIC_I2C_1_IRQ (PIC_IRQ_BASE + PIC_IRT_I2C_1_INDEX)
#define PIC_PCMCIA_IRQ (PIC_IRQ_BASE + PIC_IRT_PCMCIA_INDEX)
#define PIC_GPIO_IRQ (PIC_IRQ_BASE + PIC_IRT_GPIO_INDEX)
#define PIC_HYPER_IRQ (PIC_IRQ_BASE + PIC_IRT_HYPER_INDEX)
#define PIC_PCIX_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIX_INDEX)
#define PIC_GMAC_0_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC0_INDEX)
#define PIC_GMAC_1_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC1_INDEX)
#define PIC_GMAC_2_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC2_INDEX)
#define PIC_GMAC_3_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC3_INDEX)
#define PIC_XGS_0_IRQ (PIC_IRQ_BASE + PIC_IRT_XGS0_INDEX)
#define PIC_XGS_1_IRQ (PIC_IRQ_BASE + PIC_IRT_XGS1_INDEX)
#define PIC_HYPER_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_HYPER_FATAL_INDEX)
#define PIC_PCIX_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIX_FATAL_INDEX)
#define PIC_BRIDGE_AERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_AERR_INDEX)
#define PIC_BRIDGE_BERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_BERR_INDEX)
#define PIC_BRIDGE_TB_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_TB_INDEX)
#define PIC_BRIDGE_AERR_NMI_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_AERR_NMI_INDEX)
#define PIC_BRIDGE_ERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_ERR_INDEX)
#define PIC_PCIE_LINK0_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK0_INDEX)
#define PIC_PCIE_LINK1_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK1_INDEX)
#define PIC_PCIE_LINK2_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK2_INDEX)
#define PIC_PCIE_LINK3_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK3_INDEX)
#define PIC_PCIE_INT_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_INT__INDEX)
#define PIC_PCIE_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_FATAL_INDEX)
#define PIC_GPIO_B_IRQ (PIC_IRQ_BASE + PIC_IRT_GPIO_B_INDEX)
#define PIC_USB_IRQ (PIC_IRQ_BASE + PIC_IRT_USB_INDEX)
#define PIC_IRT_LAST_IRQ PIC_USB_IRQ
#define PIC_IRQ_IS_EDGE_TRIGGERED(irq) ( ((irq)>=PIC_TIMER_0_IRQ) && ((irq)<=PIC_TIMER_7_IRQ) )
#define PIC_IRQ_IS_IRT(irq) ( ((irq)>=PIC_IRT_FIRST_IRQ) && ((irq)<=PIC_IRT_LAST_IRQ) )
extern struct mtx xlr_pic_lock;
static __inline__ __uint32_t pic_read_control(void)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
__uint32_t reg;
mtx_lock_spin(&xlr_pic_lock);
xlr_read_reg(mmio, PIC_CTRL);
mtx_unlock_spin(&xlr_pic_lock);
return reg;
}
static __inline__ void pic_write_control(__uint32_t control)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
mtx_lock_spin(&xlr_pic_lock);
xlr_write_reg(mmio, PIC_CTRL, control);
mtx_unlock_spin(&xlr_pic_lock);
}
static __inline__ void pic_update_control(__uint32_t control)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
mtx_lock_spin(&xlr_pic_lock);
xlr_write_reg(mmio, PIC_CTRL, (control | xlr_read_reg(mmio, PIC_CTRL)));
mtx_unlock_spin(&xlr_pic_lock);
}
static __inline__ void pic_ack(int irq)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
/* ack the pic, if needed */
if (!PIC_IRQ_IS_IRT(irq)) return;
if(PIC_IRQ_IS_EDGE_TRIGGERED(irq)) {
mtx_lock_spin(&xlr_pic_lock);
xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE) ));
mtx_unlock_spin(&xlr_pic_lock);
return;
}
return;
}
static inline void pic_delayed_ack(int irq)
{
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
if (!PIC_IRQ_IS_IRT(irq)) return;
if(!PIC_IRQ_IS_EDGE_TRIGGERED(irq)) {
mtx_lock_spin(&xlr_pic_lock);
xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE) ));
mtx_unlock_spin(&xlr_pic_lock);
return;
}
}
#endif /* _RMI_PIC_H_ */

108
sys/mips/rmi/shared_structs.h Executable file
View File

@ -0,0 +1,108 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#ifndef _SHARED_STRUCTS_H
#define _SHARED_STRUCTS_H
/* If you make any changes to the below structs, shared_structs_offsets.h
* should be regenerated
*/
#define BOOT1_INFO_VERSION 0x0001
struct boot1_info {
uint64_t boot_level;
uint64_t io_base;
uint64_t output_device;
uint64_t uart_print;
uint64_t led_output;
uint64_t init;
uint64_t exit;
uint64_t warm_reset;
uint64_t wakeup;
uint64_t cpu_online_map;
uint64_t master_reentry_sp;
uint64_t master_reentry_gp;
uint64_t master_reentry_fn;
uint64_t slave_reentry_fn;
uint64_t magic_dword;
uint64_t uart_putchar;
uint64_t size;
uint64_t uart_getchar;
uint64_t nmi_handler;
uint64_t psb_version;
uint64_t mac_addr;
uint64_t cpu_frequency;
uint64_t board_version;
uint64_t malloc;
uint64_t free;
uint64_t alloc_pbuf;
uint64_t free_pbuf;
uint64_t psb_os_cpu_map;
uint64_t userapp_cpu_map;
uint64_t wakeup_os;
uint64_t psb_mem_map;
uint64_t board_major_version;
uint64_t board_minor_version;
uint64_t board_manf_revision;
uint64_t board_serial_number;
uint64_t psb_physaddr_map;
};
extern struct boot1_info xlr_boot1_info;
/* This structure is passed to all applications launched from the linux
loader through K0 register
*/
#define XLR_LOADER_INFO_MAGIC 0x600ddeed
struct xlr_loader_info {
uint32_t magic;
/* xlr_loader_shared_struct_t for CPU 0 will start here */
unsigned long sh_mem_start;
/* Size of the shared memory b/w linux apps and rmios apps */
uint32_t app_sh_mem_size;
};
/* Boot loader uses the linux mips convention */
#define BOOT1_MEMMAP_MAX 32
enum xlr_phys_memmap_t { BOOT1_MEM_RAM=1, BOOT1_MEM_ROM_DATA, BOOT1_MEM_RESERVED};
struct xlr_boot1_mem_map {
uint32_t num_entries;
struct {
uint64_t addr;
uint64_t size;
uint32_t type;
uint32_t pad;
} physmem_map[BOOT1_MEMMAP_MAX];
};
#endif

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,73 @@
/*-
* Copyright (c) 2006 Raza Microelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/uart/uart_bus_iodi.c,v 1.6.2.5 2006/02/15 09:16:01 marius Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
static int uart_iodi_probe(device_t dev);
static device_method_t uart_iodi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, uart_iodi_probe),
DEVMETHOD(device_attach, uart_bus_attach),
DEVMETHOD(device_detach, uart_bus_detach),
{ 0, 0 }
};
static driver_t uart_iodi_driver = {
uart_driver_name,
uart_iodi_methods,
sizeof(struct uart_softc),
};
static int
uart_iodi_probe(device_t dev)
{
struct uart_softc *sc;
sc = device_get_softc(dev);
sc->sc_class = &uart_ns8250_class;
/* regshft = 2, rclk = 66000000, rid = 0, chan = 0 */
return (uart_bus_probe(dev, 2, 66000000, 0, 0));
}
DRIVER_MODULE(uart, iodi, uart_iodi_driver, uart_devclass, 0, 0);

View File

@ -0,0 +1,171 @@
/*-
* Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: uart_cpu_mips_xlr.c,v 1.5 2008-07-16 20:22:39 jayachandranc Exp $
*/
/*
* Skeleton of this file was based on respective code for ARM
* code written by Olivier Houchard.
*/
/*
* XLRMIPS: This file is hacked from arm/...
*/
#include "opt_uart.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/cons.h>
#include <machine/bus.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
static int xlr_uart_probe(struct uart_bas *bas);
static void xlr_uart_init(struct uart_bas *bas, int, int, int, int);
static void xlr_uart_term(struct uart_bas *bas);
static void xlr_uart_putc(struct uart_bas *bas, int);
static int xlr_uart_poll(struct uart_bas *bas);
static int xlr_uart_getc(struct uart_bas *bas);
struct mtx xlr_uart_mtx; /*UartLock*/
struct uart_ops xlr_uart_ns8250_ops = {
.probe = xlr_uart_probe,
.init = xlr_uart_init,
.term = xlr_uart_term,
.putc = xlr_uart_putc,
.poll = xlr_uart_poll,
.getc = xlr_uart_getc,
};
bus_space_tag_t uart_bus_space_io;
bus_space_tag_t uart_bus_space_mem;
static __inline void xlr_uart_lock(struct mtx *hwmtx)
{
if(!mtx_initialized(hwmtx))
return;
if(!kdb_active && hwmtx != NULL)
mtx_lock_spin(hwmtx);
}
static __inline void xlr_uart_unlock(struct mtx *hwmtx)
{
if(!mtx_initialized(hwmtx))
return;
if(!kdb_active && hwmtx != NULL)
mtx_unlock_spin(hwmtx);
}
static int xlr_uart_probe(struct uart_bas *bas)
{
int res;
xlr_uart_lock(&xlr_uart_mtx);
res = uart_ns8250_ops.probe(bas);
xlr_uart_unlock(&xlr_uart_mtx);
return res;
}
static void xlr_uart_init(struct uart_bas *bas, int baudrate, int databits,
int stopbits, int parity)
{
xlr_uart_lock(&xlr_uart_mtx);
uart_ns8250_ops.init(bas,baudrate,databits,stopbits,parity);
xlr_uart_unlock(&xlr_uart_mtx);
}
static void xlr_uart_term(struct uart_bas *bas)
{
xlr_uart_lock(&xlr_uart_mtx);
uart_ns8250_ops.term(bas);
xlr_uart_unlock(&xlr_uart_mtx);
}
static void xlr_uart_putc(struct uart_bas *bas, int c)
{
xlr_uart_lock(&xlr_uart_mtx);
uart_ns8250_ops.putc(bas,c);
xlr_uart_unlock(&xlr_uart_mtx);
}
static int xlr_uart_poll(struct uart_bas *bas)
{
int res;
xlr_uart_lock(&xlr_uart_mtx);
res = uart_ns8250_ops.poll(bas);
xlr_uart_unlock(&xlr_uart_mtx);
return res;
}
static int xlr_uart_getc(struct uart_bas *bas)
{
return uart_ns8250_ops.getc(bas);
}
int
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
{
return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
}
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
di->ops = xlr_uart_ns8250_ops;
di->bas.chan = 0;
di->bas.bst = uart_bus_space_mem;
/* TODO Need to call bus_space_map() here */
di->bas.bsh = 0xbef14000; /* Try with UART0 */
di->bas.regshft = 2;
/* divisor = rclk / (baudrate * 16); */
di->bas.rclk = 66000000;
di->baudrate = 38400;
di->databits = 8;
di->stopbits = 1;
di->parity = UART_PARITY_NONE;
/* TODO: Read env variables for all console parameters */
return (0);
}
static void xlr_uart_mtx_init(void *dummy __unused)
{
mtx_init(&xlr_uart_mtx, "uart lock",NULL,MTX_SPIN);
}
SYSINIT(xlr_init_uart_mtx, SI_SUB_LOCK, SI_ORDER_ANY, xlr_uart_mtx_init, NULL);

View File

@ -0,0 +1,113 @@
/*-
* Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: xlr_boot1_console.c,v 1.6 2008-07-16 20:22:49 jayachandranc Exp $
*/
/*
* Adapted for XLR bootloader
* RMi
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_comconsole.h"
#include <sys/param.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/conf.h>
#include <sys/cons.h>
#include <sys/consio.h>
#include <sys/tty.h>
#include <mips/xlr/xlrconfig.h>
#include <mips/xlr/shared_structs.h>
#include <mips/xlr/shared_structs_func.h>
#include <ddb/ddb.h>
#if 0
static cn_probe_t xlr_boot1_cnprobe;
static cn_init_t xlr_boot1_cninit;
static cn_term_t xlr_boot1_cnterm;
static cn_getc_t xlr_boot1_cngetc;
static cn_checkc_t xlr_boot1_cncheckc;
static cn_putc_t xlr_boot1_cnputc;
CONS_DRIVER(xlrboot, xlr_boot1_cnprobe, xlr_boot1_cninit, xlr_boot1_cnterm, xlr_boot1_cngetc,
xlr_boot1_cncheckc, xlr_boot1_cnputc, NULL);
/*
* Device gets probed. Firmwire should be checked here probably.
*/
static void
xlr_boot1_cnprobe(struct consdev *cp)
{
cp->cn_pri = CN_NORMAL;
cp->cn_tp = NULL;
cp->cn_arg = NULL; /* softc */
cp->cn_unit = -1; /* ? */
cp->cn_flags = 0;
}
/*
* Initialization.
*/
static void
xlr_boot1_cninit(struct consdev *cp)
{
sprintf(cp->cn_name, "boot1");
}
static void
xlr_boot1_cnterm(struct consdev *cp)
{
cp->cn_pri = CN_DEAD;
cp->cn_flags = 0;
return;
}
static int
xlr_boot1_cngetc(struct consdev *cp)
{
return boot1_info_uart_getchar_func(&xlr_boot1_info);
}
static void
xlr_boot1_cnputc(struct consdev *cp, int c)
{
boot1_info_uart_putchar_func(&xlr_boot1_info, c);
}
static int
xlr_boot1_cncheckc(struct consdev *cp)
{
return 0;
}
#endif

View File

@ -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)

442
sys/mips/rmi/xlr_i2c.c Normal file
View File

@ -0,0 +1,442 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/mips/xlr/xlr_i2c.c,v 1.20.8.1 2008/08/25 23:17:51 cognet Exp $");
/*
* I2C driver for the Palm-BK3220 I2C Host adapter on the RMI XLR.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <dev/iicbus/iiconf.h>
#include <dev/iicbus/iicbus.h>
#include <mips/xlr/iomap.h>
#include <mips/include/resource.h>
#include "iicbus_if.h"
#define DEVTOIICBUS(dev) ((struct iicbus_device*)device_get_ivars(dev))
#define I2C_PALM_CFG 0x00
#define I2C_PALM_CLKDIV 0x01
#define I2C_PALM_DEVADDR 0x02
#define I2C_PALM_ADDR 0x03
#define I2C_PALM_DATAOUT 0x04
#define I2C_PALM_DATAIN 0x05
#define I2C_PALM_STATUS 0x06
#define I2C_PALM_STARTXFR 0x07
#define I2C_PALM_BYTECNT 0x08
#define I2C_PALM_HDSTATIM 0x09
/* TEST Values!! Change as required */
#define I2C_PALM_CFG_DEF 0x000000F8 /* 8-Bit Addr + POR Values */
#define I2C_PALM_CLKDIV_DEF 0x14A //0x00000052
#define I2C_PALM_HDSTATIM_DEF 0x107 //0x00000000
#define I2C_PALM_STARTXFR_RD 0x00000001
#define I2C_PALM_STARTXFR_WR 0x00000000
#define PHOENIX_IO_I2C_0_OFFSET 0x16000
#define PHOENIX_IO_I2C_1_OFFSET 0x17000
#define ARIZONA_I2c_BUS 1
int bus =1;
uint8_t current_slave;
uint8_t read_address;
static xlr_reg_t* iobase_i2c_regs;
static devclass_t xlr_i2c_devclass;
/*
* Device methods
*/
static int xlr_i2c_probe(device_t);
static int xlr_i2c_attach(device_t);
static int xlr_i2c_detach(device_t);
static int xlr_i2c_start(device_t dev, u_char slave, int timeout);
static int xlr_i2c_stop(device_t dev);
static int xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay );
static int xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout );
struct xlr_i2c_softc
{
device_t dev; /* Myself */
struct resource *mem_res; /* Memory resource */
volatile int flags;
#define RXRDY 4
#define TXRDY 0x10
int sc_started;
int twi_addr;
device_t iicbus;
};
#define MDELAY(a){ \
unsigned long local_loop = 0xfffff; \
while(local_loop--); \
}\
static void get_i2c_base(void)
{
if(bus == 0)
iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_0_OFFSET);
else
iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_1_OFFSET);
return;
}
static void palm_write(int reg, int value)
{
get_i2c_base();
xlr_write_reg(iobase_i2c_regs, reg, value);
return;
}
static int palm_read(int reg)
{
uint32_t val;
get_i2c_base();
val = xlr_read_reg(iobase_i2c_regs, reg);
return ((int) val);
}
static int palm_addr_only(uint8_t addr, uint8_t offset)
{
volatile uint32_t regVal=0x00;
palm_write(I2C_PALM_ADDR, offset);
palm_write(I2C_PALM_DEVADDR, addr);
palm_write(I2C_PALM_CFG, 0xfa);
palm_write(I2C_PALM_STARTXFR,0x02);
regVal = palm_read(I2C_PALM_STATUS);
if (regVal & 0x0008) {
printf("palm_addr_only: ACKERR. Aborting...\n");
return -1;
}
return 0;
}
static int palm_rx(uint8_t addr, uint8_t offset, uint8_t len,
uint8_t *buf)
{
volatile uint32_t regVal=0x00, ctr=0x00;
int timeOut, numBytes=0x00;
palm_write(I2C_PALM_CFG, 0xfa);
palm_write(I2C_PALM_BYTECNT, len);
palm_write(I2C_PALM_DEVADDR, addr); //DEVADDR=0x4c, 0x68
MDELAY(1);
for (numBytes=0x00; numBytes < len; numBytes++) {
palm_write(I2C_PALM_ADDR, offset+numBytes);//I2C_PALM_ADDR:offset
MDELAY(1);
if (!ctr) {
/* Trigger a READ Transaction */
palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD);
ctr++;
}
/* Error Conditions [Begin] */
regVal = palm_read(I2C_PALM_STATUS);
MDELAY(1);
if (regVal & 0x0008) {
printf("palm_rx: ACKERR. Aborting...\n");
return -1;
}
timeOut=10;
while ((regVal & 0x0030) && timeOut--) {
palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD);
regVal = palm_read(I2C_PALM_STATUS);
}
if (timeOut==0x00) {
printf("palm_rx: TimedOut on Valid STARTXFR/Arbitration\n");
return -1;
}
timeOut=10;
/* Do we have valid data from the device yet..? */
regVal &= 0x0004;
while (!regVal && timeOut--) {
regVal = palm_read(I2C_PALM_STATUS) & 0x0004;
}
if (timeOut==0x00) {
printf("palm_rx: TimedOut Waiting for Valid Data\n");
return -1;
}
/* Error Conditions [End] */
/* Read the data */
buf[numBytes] = (uint8_t)palm_read(I2C_PALM_DATAIN);
}
return 0;
}
static int wait_for_idle(void)
{
int timeOut=0x1000;
volatile uint32_t regVal=0x00;
regVal = palm_read(I2C_PALM_STATUS) & 0x0001;
while (regVal && timeOut--) {
regVal = palm_read(I2C_PALM_STATUS) & 0x0001;
}
if (timeOut == 0x00)
return -1; /* Timed Out */
else
return 0;
}
static int palm_tx(uint8_t addr, uint8_t offset, uint8_t* buf, uint8_t len)
{
volatile uint32_t regVal=0x00;
int timeOut, ctr=0x00, numBytes=len;
for (ctr=0x00; ctr<len; ctr++) {
if (wait_for_idle() < 0) {
printf("TimedOut on Waiting for I2C Bus Idle.\n");
return -EIO;
}
palm_write(I2C_PALM_CFG, 0xF8);
palm_write(I2C_PALM_BYTECNT, 0x00);
palm_write(I2C_PALM_DEVADDR, addr); //0x4c, 0x68
palm_write(I2C_PALM_ADDR, offset+numBytes-1); //offset
palm_write(I2C_PALM_DATAOUT, buf[ctr]);
palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_WR );
MDELAY(1);
regVal = palm_read(I2C_PALM_STATUS);
MDELAY(1);
if (regVal & 0x0008) {
printf("palm_tx: ACKERR. Aborting...\n");
return -1;
}
timeOut= 0x1000;
while (!(regVal & 0x0002) && timeOut) {
regVal = palm_read(I2C_PALM_STATUS);
timeOut--;
}
if (timeOut==0x00) {
printf("palm_tx: [TimeOut] SDOEMPTY Not Set\n");
return -1;
}
timeOut=1000;
while ((regVal & 0x0030) && timeOut) {
palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_WR);
regVal = palm_read(I2C_PALM_STATUS);
timeOut--;
}
if (timeOut==0x00) {
printf("palm_rx: TimedOut on Valid STARTXFR/Arbitration\n");
return -1;
}
numBytes--;
}
return 0;
}
static int
xlr_i2c_probe(device_t dev)
{
device_set_desc(dev, "I2C bus controller");
return (0);
}
/*
* We add all the devices which we know about.
* The generic attach routine will attach them if they are alive.
*/
static int
xlr_i2c_attach(device_t dev)
{
struct xlr_i2c_softc *sc;
int rid;
sc = device_get_softc(dev);
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
{
printf("not able to allocate the bus resource\n");
}
if((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL)
printf("could not allocate iicbus instance\n");
bus_generic_attach(dev);
return (0);
}
static int
xlr_i2c_detach(device_t dev)
{
bus_generic_detach(dev);
return (0);
}
/*
static int
xlr_i2c_add_child(device_t dev, int order, const char *name, int unit)
{
printf("********* %s ******** \n", __FUNCTION__);
device_add_child_ordered(dev, order, name, unit);
bus_generic_attach(dev);
return (0);
}
*/
static int xlr_i2c_start(device_t dev, u_char slave, int timeout)
{
int error =0;
struct xlr_i2c_softc *sc;
sc = device_get_softc(dev);
sc->sc_started = 1;
current_slave = (slave >> 1);
return error;
}
static int xlr_i2c_stop(device_t dev)
{
int error =0;
return error;
}
static int xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last,
int delay )
{
int error =0;
if(palm_addr_only(current_slave,read_address) == -1){
printf("I2C ADDRONLY Phase Fail.\n");
return -1;
}
if(palm_rx(current_slave,read_address,len,buf)== -1){
printf("I2C Read Fail.\n");
return -1;
}
*read = len;
return error;
}
static int xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout /* us */)
{
int error =0;
uint8_t write_address;
if(len == 1){
/* address for the next read*/
read_address=buf[0];
return error;
}
if(len < 2)
return (-1);
write_address = buf[0];
/*for write operation, buf[0] contains the register offset and
buf[1] onwards contains the value*/
palm_tx(current_slave,write_address, &buf[1], len-1);
return error;
}
static int
xlr_i2c_callback(device_t dev, int index, caddr_t *data)
{
return 0;
}
static int
xlr_i2c_repeated_start(device_t dev, u_char slave, int timeout)
{
return 0;
}
static device_method_t xlr_i2c_methods[] = {
/* device interface */
DEVMETHOD(device_probe, xlr_i2c_probe),
DEVMETHOD(device_attach, xlr_i2c_attach),
DEVMETHOD(device_detach, xlr_i2c_detach),
/* iicbus interface */
DEVMETHOD(iicbus_callback, xlr_i2c_callback),
DEVMETHOD(iicbus_repeated_start, xlr_i2c_repeated_start),
DEVMETHOD(iicbus_start, xlr_i2c_start),
DEVMETHOD(iicbus_stop, xlr_i2c_stop),
DEVMETHOD(iicbus_write, xlr_i2c_write),
DEVMETHOD(iicbus_read, xlr_i2c_read),
{ 0, 0 }
};
static driver_t xlr_i2c_driver = {
"xlr_i2c",
xlr_i2c_methods,
sizeof(struct xlr_i2c_softc),
};
DRIVER_MODULE(xlr_i2c, iodi, xlr_i2c_driver, xlr_i2c_devclass, 0, 0);

650
sys/mips/rmi/xlr_machdep.c Normal file
View File

@ -0,0 +1,650 @@
/*-
* Copyright (c) 2002-2004 Juli Mallett <jmallett@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/rtprio.h>
#include <sys/systm.h>
#include <sys/interrupt.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/ktr.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/random.h>
#include <sys/resourcevar.h>
#include <sys/sched.h>
#include <sys/sysctl.h>
#include <sys/unistd.h>
#include <sys/cons.h> /* cinit() */
#include <sys/reboot.h>
#include <sys/queue.h>
#include <sys/smp.h>
#include <sys/timetc.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/cpuinfo.h>
#include <machine/cpuregs.h>
#include <machine/frame.h>
#include <machine/hwfunc.h>
#include <machine/md_var.h>
#include <machine/asm.h>
#include <machine/pmap.h>
#include <machine/trap.h>
#include <machine/clock.h>
#include <machine/fls64.h>
#include <machine/intr_machdep.h>
#include <machine/smp.h>
#include <machine/mips-exts.h>
#include <mips/xlr/iomap.h>
#include <mips/xlr/clock.h>
#include <mips/xlr/msgring.h>
#include <mips/xlr/xlrconfig.h>
#include <mips/xlr/interrupt.h>
#include <mips/xlr/pic.h>
#ifdef XLR_PERFMON
#include <mips/xlr/perfmon.h>
#endif
void platform_prep_smp_launch(void);
unsigned long xlr_io_base = (unsigned long)(DEFAULT_XLR_IO_BASE);
/* 4KB static data aread to keep a copy of the bootload env until
the dynamic kenv is setup */
char boot1_env[4096];
extern unsigned long _gp;
/*
* Parameters from boot loader
*/
struct boot1_info xlr_boot1_info;
struct xlr_loader_info xlr_loader_info; /* FIXME : Unused */
int xlr_run_mode;
int xlr_argc;
char **xlr_argv, **xlr_envp;
uint64_t cpu_mask_info;
uint32_t xlr_online_cpumask;
#ifdef SMP
static unsigned long xlr_secondary_gp[MAXCPU];
static unsigned long xlr_secondary_sp[MAXCPU];
#endif
extern int mips_cpu_online_mask;
extern int mips_cpu_logical_mask;
extern uint32_t cpu_ltop_map[MAXCPU];
extern uint32_t cpu_ptol_map[MAXCPU];
uint32_t xlr_core_cpu_mask=0x1; /* Core 0 thread 0 is always there */
void
platform_reset(void)
{
/* FIXME : use proper define */
u_int32_t *mmio = (u_int32_t *)0xbef18000;
printf("Rebooting the system now\n");
mmio[8] = 0x1;
}
void platform_secondary_init(void)
{
#ifdef SMP
xlr_msgring_cpu_init();
/* Setup interrupts for secondary CPUs here */
platform_update_intrmask(IPI_SMP_CALL_FUNCTION);
platform_update_intrmask(IPI_STOP);
platform_update_intrmask(IPI_RENDEZVOUS);
platform_update_intrmask(IPI_AST);
platform_update_intrmask(IRQ_TIMER);
#ifdef XLR_PERFMON
platform_update_intrmask(IPI_PERFMON);
#endif
return;
#endif
}
int xlr_asid_pcpu=256; /* This the default */
int xlr_shtlb_enabled=0;
/* This function sets up the number of tlb entries available
to the kernel based on the number of threads brought up.
The ASID range also gets divided similarly.
THE NUMBER OF THREADS BROUGHT UP IN EACH CORE MUST BE THE SAME
NOTE: This function will mark all 64TLB entries as available
to the threads brought up in the core. If kernel is brought with say mask
0x33333333, no TLBs will be available to the threads in each core.
*/
static void setup_tlb_resource(void)
{
int mmu_setup;
int value = 0;
uint32_t cpu_map = xlr_boot1_info.cpu_online_map;
uint32_t thr_mask = cpu_map >> (xlr_cpu_id() << 2);
uint8_t core0 = xlr_boot1_info.cpu_online_map & 0xf;
uint8_t core_thr_mask;
int i=0, count=0;
/* If CPU0 did not enable shared TLB, other cores need to follow */
if((xlr_cpu_id() != 0) && (xlr_shtlb_enabled == 0))
return;
/* First check if each core is brought up with the same mask */
for(i=1; i < 8; i++) {
core_thr_mask = cpu_map >> (i << 2);
core_thr_mask &= 0xf;
if(core_thr_mask && core_thr_mask != core0){
printf
("Each core must be brought with same cpu mask\n");
printf("Cannot enabled shared TLB. ");
printf("Falling back to split TLB mode\n");
return;
}
}
xlr_shtlb_enabled = 1;
for(i=0;i<4;i++) if (thr_mask & (1<<i)) count++;
switch(count) {
case 1:
xlr_asid_pcpu = 256;
break;
case 2:
xlr_asid_pcpu = 128;
value = 0x2;
break;
default:
xlr_asid_pcpu = 64;
value = 0x3;
break;
}
mmu_setup = read_32bit_phnx_ctrl_reg(4, 0);
mmu_setup = mmu_setup & ~0x06;
mmu_setup |= (value << 1);
/* turn on global mode */
mmu_setup |= 0x01;
write_32bit_phnx_ctrl_reg(4, 0, mmu_setup);
}
/*
* Platform specific register setup for CPUs
* XLR has control registers accessible with MFCR/MTCR instructions, this
* code initialized them from the environment variable xlr.cr of form:
* xlr.cr=reg:val[,reg:val]*, all values in hex.
* To enable shared TLB option use xlr.shtlb=1
*/
void platform_cpu_init()
{
char *hw_env;
char *start, *end;
uint32_t reg,val;
int thr_id = xlr_thr_id();
if(thr_id == 0) {
if ((hw_env = getenv("xlr.shtlb")) != NULL) {
start = hw_env;
reg = strtoul(start, &end, 16);
if(start != end && reg != 0)
setup_tlb_resource();
} else {
/* By default TLB entries are shared in a core */
setup_tlb_resource();
}
}
if ((hw_env = getenv("xlr.cr")) == NULL)
return;
start = hw_env;
while (*start != '\0') {
reg = strtoul(start, &end, 16);
if (start == end) {
printf("Invalid value in xlr.cr %s, cannot read a hex value at %d\n",
hw_env, start - hw_env);
goto err_return;
}
if (*end != ':') {
printf("Invalid format in xlr.cr %s, ':' expected at pos %d\n",
hw_env, end - hw_env);
goto err_return;
}
start = end + 1; /* step over ':' */
val = strtoul(start, &end, 16);
if (start == end) {
printf("Invalid value in xlr.cr %s, cannot read a hex value at pos %d\n",
hw_env, start - hw_env);
goto err_return;
}
if (*end != ',' && *end != '\0') {
printf("Invalid format in xlr.cr %s, ',' expected at pos %d\n",
hw_env, end - hw_env);
goto err_return;
}
xlr_mtcr(reg, val);
if (*end == ',')
start = end + 1; /* skip over ',' */
else
start = end;
}
freeenv(hw_env);
return;
err_return:
panic("Invalid xlr.cr setting!");
return;
}
#ifdef SMP
extern void xlr_secondary_start(unsigned long, unsigned long, unsigned long);
static void xlr_secondary_entry(void *data)
{
unsigned long sp,gp;
unsigned int cpu = (xlr_cpu_id()<<2)+xlr_thr_id();
sp = xlr_secondary_sp[cpu];
gp = xlr_secondary_gp[cpu];
xlr_secondary_start((unsigned long)mips_secondary_wait, sp, gp);
}
#endif
static void xlr_set_boot_flags(void)
{
char *p;
for (p = getenv("boot_flags"); p && *p != '\0'; p++) {
switch(*p) {
case 'd':
case 'D':
boothowto |= RB_KDB;
break;
case 'g':
case 'G':
boothowto |= RB_GDB;
break;
case 'v':
case 'V':
boothowto |= RB_VERBOSE;
break;
case 's': /* single-user (default, supported for sanity) */
case 'S':
boothowto |= RB_SINGLE;
break;
default:
printf("Unrecognized boot flag '%c'.\n", *p);
break;
}
}
if (p)
freeenv(p);
return;
}
extern uint32_t _end;
void
platform_start()
{
vm_size_t physsz = 0;
int i, j;
struct xlr_boot1_mem_map *boot_map;
#ifdef SMP
uint32_t tmp;
void (*wakeup)(void *, void *, unsigned int);
#endif
/* XXX FIXME the code below is not 64 bit clean */
/* Save boot loader and other stuff from scratch regs */
xlr_boot1_info = *(struct boot1_info *)read_c0_register32(MIPS_COP_0_OSSCRATCH, 0);
cpu_mask_info = read_c0_register64(MIPS_COP_0_OSSCRATCH, 1);
xlr_online_cpumask = read_c0_register32(MIPS_COP_0_OSSCRATCH, 2);
xlr_run_mode = read_c0_register32(MIPS_COP_0_OSSCRATCH, 3);
xlr_argc = read_c0_register32(MIPS_COP_0_OSSCRATCH, 4);
xlr_argv = (char **)read_c0_register32(MIPS_COP_0_OSSCRATCH, 5);
xlr_envp = (char **)read_c0_register32(MIPS_COP_0_OSSCRATCH, 6);
/* TODO: Verify the magic number here */
/*FIXMELATER: xlr_boot1_info.magic_number */
/* initialize console so that we have printf */
boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */
/* clockrate used by delay, so initialize it here */
hw_clockrate = xlr_boot1_info.cpu_frequency/1000000 ;
cninit();
printf("Environment (from %d args):\n", xlr_argc-1);
if (xlr_argc == 1)
printf("\tNone\n");
for(i=1,j=0; i<xlr_argc; i++) {
int len = strlen(xlr_argv[i]);
if (j + len + 2 > sizeof(boot1_env)) {
printf("*** Environment could not be copied in full\n");
break;
}
printf("\t%s\n", xlr_argv[i]);
memcpy(&boot1_env[j], xlr_argv[i], len+1); /* copy the '\0' too */
j += len+1;
}
boot1_env[j] = '\0';
kern_envp = boot1_env;
xlr_set_boot_flags();
/* get physical memory info from boot loader*/
boot_map = (struct xlr_boot1_mem_map *)
(unsigned long)xlr_boot1_info.psb_mem_map;
for(i=0, j=0; i<boot_map->num_entries; i++, j+=2) {
if (boot_map->physmem_map[i].type == BOOT1_MEM_RAM) {
if (j == 14) {
printf("*** ERROR *** memory map too large ***\n");
break;
}
if (j == 0) {
/*TODO FIXME */
/* start after kernel end */
phys_avail[0] = (vm_paddr_t)
MIPS_KSEG0_TO_PHYS(&_end) + 0x20000;
/* boot loader start */
/* HACK to Use bootloaders memory region */
/*TODO FIXME */
if(boot_map->physmem_map[0].size == 0x0c000000) {
boot_map->physmem_map[0].size = 0x0ff00000;
}
phys_avail[1] = boot_map->physmem_map[0].addr +
boot_map->physmem_map[0].size;
} else {
/*
* Can't use this code yet, because most of the fixed allocations happen from
* the biggest physical area. If we have more than 512M memory the kernel will try
* to map from the second are which is not in KSEG0 and not mapped
*/
phys_avail[j] = (vm_paddr_t)
boot_map->physmem_map[i].addr;
phys_avail[j+1] = phys_avail[j] +
boot_map->physmem_map[i].size;
#if 0 /* FIXME TOD0 */
phys_avail[j] = phys_avail[j+1] = 0;
#endif
}
physsz += boot_map->physmem_map[i].size;
}
}
/* FIXME XLR TODO */
phys_avail[j] = phys_avail[j+1] = 0;
realmem = physmem = btoc(physsz);
/*Store pcpu in scratch 5*/
write_c0_register32(MIPS_COP_0_OSSCRATCH,5,pcpup);
/* Set up hz, among others. */
mips_init();
pcpup = (struct pcpu *)NULL; /* TODO To be removed */
#ifdef SMP
/*If thread 0 of any core is not available then mark whole core as
not available*/
tmp = xlr_boot1_info.cpu_online_map;
for(i=4; i<MAXCPU; i += 4){
if((tmp & (0xf<<i)) && !(tmp & (0x1<<i))){
/*Oopps.. thread 0 is not available. Disable whole
core*/
tmp = tmp & ~(0xf<<i);
printf("WARNING: Core %d is disabled because thread 0"
" of this core is not enabled.\n",i/4);
}
}
xlr_boot1_info.cpu_online_map = tmp;
/* Wakeup Other cpus, and put them in bsd park code. */
for(i=1,j=1;i<32;i++){
/* Allocate stack for all other cpus from fbsd kseg0 memory. */
if((1U<<i) & xlr_boot1_info.cpu_online_map){
xlr_secondary_gp[i] =
pmap_steal_unmapped_memory(PAGE_SIZE) ;
if(!xlr_secondary_gp[i])
panic("Allocation failed for secondary cpu stacks");
xlr_secondary_sp[i] =
xlr_secondary_gp[i]+PAGE_SIZE-CALLFRAME_SIZ;
xlr_secondary_gp[i] = (unsigned long)&_gp;
/*Build ltop and ptol cpu map.*/
cpu_ltop_map[j] = i;
cpu_ptol_map[i] = j;
if((i & 0x3) == 0) /*store thread0 of each core */
xlr_core_cpu_mask |= (1<<j);
mips_cpu_logical_mask |= (1<<j);
j++;
}
}
mips_cpu_online_mask |= xlr_boot1_info.cpu_online_map;
wakeup = ((void (*)(void *, void *, unsigned int))
(unsigned long)(xlr_boot1_info.wakeup));
printf("Waking up CPUs 0x%llx.\n", xlr_boot1_info.cpu_online_map & ~(0x1U));
if(xlr_boot1_info.cpu_online_map & ~(0x1U))
wakeup(xlr_secondary_entry, 0,
(unsigned int)xlr_boot1_info.cpu_online_map);
#endif
/* xlr specific post initialization */
/* The expectation is that mutex_init() is already done
* in mips_init()
* XXX NOTE: We may need to move this to SMP based init code
* for each CPU, later.
*/
on_chip_init();
tick_init();
}
void
platform_identify(void)
{
printf("Board [%d:%d], processor 0x%08x\n", (int) xlr_boot1_info.board_major_version,
(int) xlr_boot1_info.board_minor_version, mips_rd_prid());
}
/*
* XXX Maybe return the state of the watchdog in enter, and pass it to
* exit? Like spl().
*/
void
platform_trap_enter(void)
{
}
void
platform_trap_exit(void)
{
}
void
platform_update_intrmask(int intr)
{
write_c0_eimr64(read_c0_eimr64() | (1ULL<<intr));
}
void disable_msgring_int(void *arg) ;
void enable_msgring_int(void *arg) ;
void xlr_msgring_handler(struct trapframe *tf);
void msgring_process_fast_intr(void *arg);
struct msgring_ithread {
struct thread *i_thread;
u_int i_pending;
u_int i_flags;
int i_cpu;
};
struct msgring_ithread msgring_ithreads[MAXCPU];
char ithd_name[MAXCPU][32];
void
msgring_process_fast_intr(void *arg)
{
int cpu = PCPU_GET(cpuid);
volatile struct msgring_ithread *it;
struct proc *p;
struct thread *td;
/* wakeup an appropriate intr_thread for processing this interrupt */
it = (volatile struct msgring_ithread *)&msgring_ithreads[cpu];
td = it->i_thread;
p = td->td_proc;
/* Interrupt thread will enable the interrupts after processing
all messages
*/
mtx_lock_spin(&sched_lock);
disable_msgring_int(NULL);
it->i_pending = 1;
if (TD_AWAITING_INTR(td)) {
CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid,
p->p_comm);
TD_CLR_IWAIT(td);
setrunqueue(td, SRQ_INTR);
} else {
CTR4(KTR_INTR, "%s: pid %d (%s): state %d",
__func__, p->p_pid, p->p_comm, td->td_state);
}
mtx_unlock_spin(&sched_lock);
}
#define MIT_DEAD 4
static void
msgring_process(void * arg)
{
volatile struct msgring_ithread *ithd;
struct thread *td;
struct proc *p;
td = curthread;
p = td->td_proc;
ithd = (volatile struct msgring_ithread *)arg;
KASSERT(ithd->i_thread == td,
("%s:msg_ithread and proc linkage out of sync", __func__));
/* First bind this thread to the right CPU */
mtx_lock_spin(&sched_lock);
sched_bind(td, ithd->i_cpu);
mtx_unlock_spin(&sched_lock);
// printf("Started %s on CPU %d\n", __FUNCTION__, ithd->i_cpu);
while(1) {
if (ithd->i_flags & MIT_DEAD) {
CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__,
p->p_pid, p->p_comm);
kthread_exit(0);
}
while (ithd->i_pending) {
/*
* This might need a full read and write barrier
* to make sure that this write posts before any
* of the memory or device accesses in the
* handlers.
*/
atomic_store_rel_int(&ithd->i_pending, 0);
xlr_msgring_handler(NULL);
}
mtx_lock_spin(&sched_lock);
if (!ithd->i_pending && !(ithd->i_flags & MIT_DEAD)) {
TD_SET_IWAIT(td);
enable_msgring_int(NULL);
mi_switch(SW_VOL, NULL);
}
mtx_unlock_spin(&sched_lock);
}
}
void platform_prep_smp_launch(void)
{
int cpu;
uint32_t cpu_mask;
struct msgring_ithread *ithd;
struct thread *td;
struct proc *p;
int error;
cpu_mask = PCPU_GET(cpumask) | PCPU_GET(other_cpus);
/* Create kernel threads for message ring interrupt processing */
/* Currently create one task for thread 0 of each core */
for(cpu=0; cpu < MAXCPU; cpu+=1) {
if(!((1 << cpu) & cpu_mask))
continue;
if((cpu_ltop_map[cpu]%4) != 0)
continue;
ithd = &msgring_ithreads[cpu];
sprintf(ithd_name[cpu], "msg_intr%d", cpu);
error = kthread_create(msgring_process, (void *)ithd, &p,
RFSTOPPED | RFHIGHPID, 0, "%s", ithd_name[cpu]);
if (error)
panic("kthread_create() failed with %d", error);
td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */
mtx_lock_spin(&sched_lock);
td->td_ksegrp->kg_pri_class = PRI_ITHD;
TD_SET_IWAIT(td);
mtx_unlock_spin(&sched_lock);
td->td_pflags |= TDP_ITHREAD;
ithd->i_thread = td;
ithd->i_pending = 0;
ithd->i_cpu = cpu;
CTR2(KTR_INTR, "%s: created %s", __func__, ithd_name[cpu]);
}
}

410
sys/mips/rmi/xlr_pci.c Normal file
View File

@ -0,0 +1,410 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/md_var.h>
#include <machine/mips-exts.h>
#include <machine/cpuregs.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <sys/rman.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcib_private.h>
#include <mips/xlr/iomap.h>
#include <mips/xlr/pic.h>
#include <mips/xlr/shared_structs.h>
#include <mips/xlr/board.h>
#include <mips/pci/pcibus.h>
#include "pcib_if.h"
#define LSU_CFG0_REGID 0
#define LSU_CERRLOG_REGID 9
#define LSU_CERROVF_REGID 10
#define LSU_CERRINT_REGID 11
#define SWAP32(x)\
(((x) & 0xff000000) >> 24) | \
(((x) & 0x000000ff) << 24) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x00ff0000) >> 8)
/* MSI support */
#define MSI_MIPS_ADDR_DEST 0x000ff000
#define MSI_MIPS_ADDR_RH 0x00000008
# define MSI_MIPS_ADDR_RH_OFF 0x00000000
# define MSI_MIPS_ADDR_RH_ON 0x00000008
#define MSI_MIPS_ADDR_DM 0x00000004
# define MSI_MIPS_ADDR_DM_PHYSICAL 0x00000000
# define MSI_MIPS_ADDR_DM_LOGICAL 0x00000004
/* Fields in data for Intel MSI messages. */
#define MSI_MIPS_DATA_TRGRMOD 0x00008000 /* Trigger mode */
# define MSI_MIPS_DATA_TRGREDG 0x00000000 /* edge */
# define MSI_MIPS_DATA_TRGRLVL 0x00008000 /* level */
#define MSI_MIPS_DATA_LEVEL 0x00004000 /* Polarity. */
# define MSI_MIPS_DATA_DEASSERT 0x00000000
# define MSI_MIPS_DATA_ASSERT 0x00004000
#define MSI_MIPS_DATA_DELMOD 0x00000700 /* Delivery Mode */
# define MSI_MIPS_DATA_DELFIXED 0x00000000 /* fixed */
# define MSI_MIPS_DATA_DELLOPRI 0x00000100 /* lowest priority */
#define MSI_MIPS_DATA_INTVEC 0x000000ff
/*
* Build Intel MSI message and data values from a source. AMD64 systems
* seem to be compatible, so we use the same function for both.
*/
#define MIPS_MSI_ADDR(cpu) \
(MSI_MIPS_ADDR_BASE | (cpu) << 12 | \
MSI_MIPS_ADDR_RH_OFF | MSI_MIPS_ADDR_DM_PHYSICAL)
#define MIPS_MSI_DATA(irq) \
(MSI_MIPS_DATA_TRGRLVL | MSI_MIPS_DATA_DELFIXED | \
MSI_MIPS_DATA_ASSERT | (irq))
struct xlr_hose_softc {
int junk; /* no softc */
};
static devclass_t pcib_devclass;
static int pci_bus_status = 0;
static void *pci_config_base;
static uint32_t pci_cfg_read_32bit(uint32_t addr);
static void pci_cfg_write_32bit(uint32_t addr, uint32_t data);
static int
xlr_pcib_probe(device_t dev)
{
device_set_desc(dev, "xlr system bridge controller");
pci_init_resources();
pci_config_base = (void *)MIPS_PHYS_TO_KSEG1(DEFAULT_PCI_CONFIG_BASE);
pci_bus_status = 1;
return 0;
}
static int
xlr_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
{
#if 0
device_printf(dev, "xlr_pcib_read_ivar : read ivar %d for child %s\n", which, device_get_nameunit(child));
#endif
switch (which) {
case PCIB_IVAR_BUS:
*result = 0;
return 0;
}
return ENOENT;
}
static int
xlr_pcib_maxslots(device_t dev)
{
if (xlr_board_info.is_xls)
return 4;
else
return 32;
}
#define pci_cfg_offset(bus,slot,devfn,where) (((bus)<<16) + ((slot) << 11)+((devfn)<<8)+(where))
static __inline__ void disable_and_clear_cache_error(void)
{
uint64_t lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID);
lsu_cfg0 = lsu_cfg0 & ~0x2e;
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0);
/* Clear cache error log */
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0);
}
static __inline__ void clear_and_enable_cache_error(void)
{
uint64_t lsu_cfg0 = 0;
/* first clear the cache error logging register */
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0);
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERROVF_REGID, 0);
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRINT_REGID, 0);
lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID);
lsu_cfg0 = lsu_cfg0 | 0x2e;
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0);
}
static uint32_t phoenix_pciread(u_int b, u_int s, u_int f,
u_int reg, int width)
{
uint32_t data = 0;
if ((width == 2) && (reg & 1))
return 0xFFFFFFFF;
else if ((width == 4) && (reg & 3))
return 0xFFFFFFFF;
if (pci_bus_status)
data = pci_cfg_read_32bit(pci_cfg_offset(b, s, f, reg));
else
data = 0xFFFFFFFF;
if (width == 1)
return ((data >> ((reg & 3) << 3)) & 0xff);
else if (width == 2)
return ((data >> ((reg & 3) << 3)) & 0xffff);
else
return data;
}
static void phoenix_pciwrite(u_int b, u_int s, u_int f,
u_int reg, u_int val, int width)
{
uint32_t cfgaddr = pci_cfg_offset(b, s, f, reg);
uint32_t data = 0;
if ((width == 2) && (reg & 1))
return ;
else if ((width == 4) && (reg & 3))
return ;
if (!pci_bus_status)
return ;
if (width == 1) {
data = pci_cfg_read_32bit(cfgaddr);
data = (data & ~(0xff << ((reg & 3) << 3))) |
(val << ((reg & 3) << 3));
} else if (width == 2) {
data = pci_cfg_read_32bit(cfgaddr);
data = (data & ~(0xffff << ((reg & 3) << 3))) |
(val << ((reg & 3) << 3));
} else {
data = val;
}
pci_cfg_write_32bit(cfgaddr, data);
return ;
}
static uint32_t pci_cfg_read_32bit(uint32_t addr)
{
uint32_t temp = 0;
uint32_t *p = (uint32_t *) ((uint32_t)pci_config_base + (addr & ~3));
uint64_t cerr_cpu_log = 0;
disable_and_clear_cache_error();
temp = SWAP32(*p);
/* Read cache err log */
cerr_cpu_log = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID);
if(cerr_cpu_log)
{
/* Device don't exist. */
temp = ~0x0;
}
clear_and_enable_cache_error();
return temp;
}
static void pci_cfg_write_32bit(uint32_t addr, uint32_t data)
{
unsigned int *p = (unsigned int *)((uint32_t)pci_config_base + (addr & ~3));
*p = SWAP32(data);
}
static u_int32_t
xlr_pcib_read_config(device_t dev, u_int b, u_int s, u_int f,
u_int reg, int width)
{
return phoenix_pciread(b, s, f, reg, width);
}
static void
xlr_pcib_write_config(device_t dev, u_int b, u_int s, u_int f,
u_int reg, u_int32_t val, int width)
{
phoenix_pciwrite(b, s, f, reg, val, width);
}
static int xlr_pcib_attach(device_t dev)
{
device_add_child(dev, "pci", 0);
bus_generic_attach(dev);
return 0;
}
#define PCIE_LINK_STATE 0x4000
static void
xlr_pcib_identify(driver_t *driver, device_t parent)
{
xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET);
xlr_reg_t reg_link0 = xlr_read_reg(pcie_mmio_le, (0x80 >> 2));
xlr_reg_t reg_link1 = xlr_read_reg(pcie_mmio_le, (0x84 >> 2));
if ((uint16_t)reg_link0 & PCIE_LINK_STATE) {
device_printf(parent, "Link 0 up\n");
}
if ((uint16_t)reg_link1 & PCIE_LINK_STATE) {
device_printf(parent, "Link 1 up\n");
}
BUS_ADD_CHILD(parent, 0, "pcib", 0);
}
static int
xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs);
static int
xlr_release_msi(device_t pcib, device_t dev, int count, int *irqs);
static int
xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs)
{
int pciirq;
int i;
device_t parent, tmp;
/* find the lane on which the slot is connected to */
tmp = dev;
while (1) {
parent = device_get_parent(tmp);
if (parent == NULL || parent == pcib) {
device_printf(dev, "Cannot find parent bus\n");
return ENXIO;
}
if (strcmp(device_get_nameunit(parent), "pci0") == 0)
break;
tmp = parent;
}
switch (pci_get_slot(tmp)) {
case 0: pciirq = PIC_PCIE_LINK0_IRQ; break;
case 1: pciirq = PIC_PCIE_LINK1_IRQ; break;
case 2: pciirq = PIC_PCIE_LINK2_IRQ; break;
case 3: pciirq = PIC_PCIE_LINK3_IRQ; break;
default: return ENXIO;
}
irqs[0] = pciirq;
/*
For now put in some fixed values for the other requested MSI,
TODO handle multiple messages
*/
for (i=1; i<count; i++)
irqs[i] = pciirq + 64*i;
return 0;
}
static int
xlr_release_msi(device_t pcib, device_t dev, int count, int *irqs)
{
device_printf(dev, "%s: msi release %d\n", device_get_nameunit(pcib), count);
return 0;
}
static int
xlr_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data);
static int
xlr_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data)
{
switch(irq) {
case PIC_PCIE_LINK0_IRQ:
case PIC_PCIE_LINK1_IRQ:
case PIC_PCIE_LINK2_IRQ:
case PIC_PCIE_LINK3_IRQ:
*addr = MIPS_MSI_ADDR(0);
*data = MIPS_MSI_DATA(irq);
return 0;
default:
device_printf(dev, "%s: map_msi for irq %d - ignored", device_get_nameunit(pcib),
irq);
return (ENXIO);
}
}
static device_method_t xlr_pcib_methods[] = {
/* Device interface */
DEVMETHOD(device_identify, xlr_pcib_identify),
DEVMETHOD(device_probe, xlr_pcib_probe),
DEVMETHOD(device_attach, xlr_pcib_attach),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_read_ivar, xlr_pcib_read_ivar),
DEVMETHOD(bus_alloc_resource, xlr_pci_alloc_resource),
DEVMETHOD(bus_release_resource, pci_release_resource),
DEVMETHOD(bus_activate_resource, pci_activate_resource),
DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
DEVMETHOD(bus_setup_intr, mips_platform_pci_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
/* pcib interface */
DEVMETHOD(pcib_maxslots, xlr_pcib_maxslots),
DEVMETHOD(pcib_read_config, xlr_pcib_read_config),
DEVMETHOD(pcib_write_config, xlr_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, mips_pci_route_interrupt),
DEVMETHOD(pcib_alloc_msi, xlr_alloc_msi),
DEVMETHOD(pcib_release_msi, xlr_release_msi),
DEVMETHOD(pcib_map_msi, xlr_map_msi),
{ 0, 0 }
};
static driver_t xlr_pcib_driver = {
"pcib",
xlr_pcib_methods,
sizeof(struct xlr_hose_softc),
};
DRIVER_MODULE(pcib, nexus, xlr_pcib_driver, pcib_devclass, 0, 0);

327
sys/mips/rmi/xlrconfig.h Normal file
View File

@ -0,0 +1,327 @@
/*-
* Copyright (c) 2003-2009 RMI Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RMI_BSD */
#ifndef XLRCONFIG_H
#define XLRCONFIG_H
#include <sys/types.h>
#include <mips/xlr/shared_structs.h>
#include <mips/xlr/shared_structs_func.h>
#define read_c0_register32(reg, sel) \
({ unsigned int __rv; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set mips32\n\t" \
"mfc0\t%0,$%1,%2\n\t" \
".set\tpop" \
: "=r" (__rv) : "i" (reg), "i" (sel) ); \
__rv;})
#define write_c0_register32(reg, sel, value) \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set mips32\n\t" \
"mtc0\t%0,$%1,%2\n\t" \
".set\tpop" \
: : "r" (value), "i" (reg), "i" (sel) );
#define read_c0_register64(reg, sel) \
({ unsigned int __high, __low; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set mips64\n\t" \
"dmfc0\t $8, $%2, %3\n\t" \
"dsrl32\t%0, $8, 0\n\t" \
"dsll32\t$8, $8, 0\n\t" \
"dsrl32\t%1, $8, 0\n\t" \
".set\tpop" \
: "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\
(((unsigned long long)__high << 32) | __low);})
#define write_c0_register64(reg, sel, value) \
do{ \
unsigned int __high = val>>32; \
unsigned int __low = val & 0xffffffff; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set mips64\n\t" \
"dsll32\t$8, %1, 0\n\t" \
"dsll32\t$9, %0, 0\n\t" \
"or\t $8, $8, $9\n\t" \
"dmtc0\t $8, $%2, %3\n\t" \
".set\tpop" \
:: "r"(high), "r"(low), "i"(reg), "i"(sel):"$8", "$9");\
} while(0)
#define read_c2_register32(reg, sel) \
({ unsigned int __rv; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set mips32\n\t" \
"mfc2\t%0,$%1,%2\n\t" \
".set\tpop" \
: "=r" (__rv) : "i" (reg), "i" (sel) ); \
__rv;})
#define write_c2_register32(reg, sel, value) \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set mips32\n\t" \
"mtc2\t%0,$%1,%2\n\t" \
".set\tpop" \
: : "r" (value), "i" (reg), "i" (sel) );
#define read_c2_register64(reg, sel) \
({ unsigned int __high, __low; \
__asm__ __volatile__( \
".set mips64\n\t" \
"dmfc2\t $8, $%2, %3\n\t" \
"dsrl32\t%0, $8, 0\n\t" \
"dsll32\t$8, $8, 0\n\t" \
"dsrl32\t%1, $8, 0\n\t" \
".set\tmips0" \
: "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\
(((unsigned long long)__high << 32) | __low);})
#define write_c2_register64(reg, sel, value) \
do{ \
unsigned int __high = value>>32; \
unsigned int __low = value & 0xffffffff; \
__asm__ __volatile__( \
".set mips64\n\t" \
"dsll32\t$8, %1, 0\n\t" \
"dsll32\t$9, %0, 0\n\t" \
"dsrl32\t$8, $8, 0\n\t" \
"or\t $8, $8, $9\n\t" \
"dmtc2\t $8, $%2, %3\n\t" \
".set\tmips0" \
:: "r"(__high), "r"(__low), \
"i"(reg), "i"(sel) \
:"$8", "$9"); \
} while(0)
#if 0
#define xlr_processor_id() \
({int __id; \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".word 0x40088007\n" \
"srl $8, $8, 10\n" \
"andi %0, $8, 0x3f\n" \
".set pop\n" \
: "=r" (__id) : : "$8"); \
__id;})
#endif
#define xlr_cpu_id() \
({int __id; \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".word 0x40088007\n" \
"srl $8, $8, 4\n" \
"andi %0, $8, 0x7\n" \
".set pop\n" \
: "=r" (__id) : : "$8"); \
__id;})
#define xlr_thr_id() \
({int __id; \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".word 0x40088007\n" \
"andi %0, $8, 0x03\n" \
".set pop\n" \
: "=r" (__id) : : "$8"); \
__id;})
/* Additional registers on the XLR */
#define MIPS_COP_0_OSSCRATCH 22
#define XLR_CACHELINE_SIZE 32
#define XLR_MAX_CORES 8
/* functions to write to and read from the extended
* cp0 registers.
* EIRR : Extended Interrupt Request Register
* cp0 register 9 sel 6
* bits 0...7 are same as cause register 8...15
* EIMR : Extended Interrupt Mask Register
* cp0 register 9 sel 7
* bits 0...7 are same as status register 8...15
*/
static inline uint64_t read_c0_eirr64(void)
{
__uint32_t high, low;
__asm__ __volatile__ (
".set push\n"
".set noreorder\n"
".set noat\n"
".set mips4\n"
".word 0x40214806 \n\t"
"nop \n\t"
"dsra32 %0, $1, 0 \n\t"
"sll %1, $1, 0 \n\t"
".set pop\n"
: "=r" (high), "=r" (low)
);
return ( ((__uint64_t)high) << 32) | low;
}
static inline __uint64_t read_c0_eimr64(void)
{
__uint32_t high, low;
__asm__ __volatile__ (
".set push\n"
".set noreorder\n"
".set noat\n"
".set mips4\n"
".word 0x40214807 \n\t"
"nop \n\t"
"dsra32 %0, $1, 0 \n\t"
"sll %1, $1, 0 \n\t"
".set pop\n"
: "=r" (high), "=r" (low)
);
return ( ((__uint64_t)high) << 32) | low;
}
static inline void write_c0_eirr64(__uint64_t value)
{
__uint32_t low, high;
high = value >> 32;
low = value & 0xffffffff;
__asm__ __volatile__ (
".set push\n"
".set noreorder\n"
".set noat\n"
".set mips4\n\t"
"dsll32 $2, %1, 0 \n\t"
"dsll32 $1, %0, 0 \n\t"
"dsrl32 $2, $2, 0 \n\t"
"or $1, $1, $2 \n\t"
".word 0x40a14806 \n\t"
"nop \n\t"
".set pop\n"
:
: "r" (high), "r" (low)
: "$1", "$2");
}
static inline void write_c0_eimr64(__uint64_t value)
{
__uint32_t low, high;
high = value >> 32;
low = value & 0xffffffff;
__asm__ __volatile__ (
".set push\n"
".set noreorder\n"
".set noat\n"
".set mips4\n\t"
"dsll32 $2, %1, 0 \n\t"
"dsll32 $1, %0, 0 \n\t"
"dsrl32 $2, $2, 0 \n\t"
"or $1, $1, $2 \n\t"
".word 0x40a14807 \n\t"
"nop \n\t"
".set pop\n"
:
: "r" (high), "r" (low)
: "$1", "$2");
}
static __inline__ int xlr_test_and_set(int *lock)
{
int oldval = 0;
__asm__ __volatile__ (".set push\n"
".set noreorder\n"
"move $9, %2\n"
"li $8, 1\n"
//"swapw $8, $9\n"
".word 0x71280014\n"
"move %1, $8\n"
".set pop\n"
: "+m" (*lock), "=r" (oldval)
: "r" ((unsigned long)lock)
: "$8", "$9"
);
return (oldval == 0 ? 1/*success*/ : 0/*failure*/);
}
static __inline__ uint32_t xlr_mfcr(uint32_t reg)
{
uint32_t val;
__asm__ __volatile__ (
"move $8, %1\n"
".word 0x71090018\n"
"move %0, $9\n"
: "=r"(val)
: "r"(reg) : "$8", "$9");
return val;
}
static __inline__ void xlr_mtcr(uint32_t reg, uint32_t val)
{
__asm__ __volatile__ (
"move $8, %1\n"
"move $9, %0\n"
".word 0x71090019\n"
::"r"(val), "r"(reg)
: "$8", "$9");
}
#endif

305
sys/mips/rmi/xls_ehci.c Normal file
View File

@ -0,0 +1,305 @@
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Lennart Augustsson (augustss@carlstedt.se) at
* Carlstedt Research & Technology.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.18.2.4 2008/04/23 18:54:51 jhb Exp $");
/*
* USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
*
* The EHCI 1.0 spec can be found at
* http://developer.intel.com/technology/usb/download/ehci-r10.pdf
* and the USB 2.0 spec at
* http://www.usb.org/developers/docs/usb_20.zip
*/
/* The low level controller code for EHCI has been split into
* PCI probes and EHCI specific code. This was done to facilitate the
* sharing of code between *BSD's
*/
#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/queue.h>
#include <sys/lockmgr.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_mem.h>
#include <dev/usb/ehcireg.h>
#include <dev/usb/ehcivar.h>
#ifdef USB_DEBUG
#define EHCI_DEBUG USB_DEBUG
#define DPRINTF(x) do { if (ehcidebug) logprintf x; } while (0)
extern int ehcidebug;
#else
#define DPRINTF(x)
#endif
static int ehci_xls_attach(device_t self);
static int ehci_xls_detach(device_t self);
static int ehci_xls_shutdown(device_t self);
static int ehci_xls_suspend(device_t self);
static int ehci_xls_resume(device_t self);
static void ehci_xls_givecontroller(device_t self);
static void ehci_xls_takecontroller(device_t self);
static int
ehci_xls_suspend(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
int err;
err = bus_generic_suspend(self);
if (err)
return (err);
ehci_power(PWR_SUSPEND, sc);
return 0;
}
static int
ehci_xls_resume(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
ehci_xls_takecontroller(self);
ehci_power(PWR_RESUME, sc);
bus_generic_resume(self);
return 0;
}
static int
ehci_xls_shutdown(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
int err;
err = bus_generic_shutdown(self);
if (err)
return (err);
ehci_shutdown(sc);
ehci_xls_givecontroller(self);
return 0;
}
static const char *xlr_usb_dev_desc = "RMI XLR USB 2.0 controller";
static const char *xlr_vendor_desc = "RMI Corp";
static int
ehci_xls_probe(device_t self)
{
/* TODO see if usb is enabled on the board */
device_set_desc(self, xlr_usb_dev_desc);
return BUS_PROBE_DEFAULT;
}
static int
ehci_xls_attach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
device_t parent;
device_t *neighbors;
int err;
int rid;
int count;
int res;
sc->sc_bus.usbrev = USBREV_2_0;
rid = 0;
sc->io_res = bus_alloc_resource(self, SYS_RES_MEMORY, &rid,
0ul, ~0ul, 0x400, RF_ACTIVE);
if (!sc->io_res) {
device_printf(self, "Could not map memory\n");
return ENXIO;
}
sc->iot = rman_get_bustag(sc->io_res);
sc->ioh = rman_get_bushandle(sc->io_res);
rid = 0;
sc->irq_res = bus_alloc_resource(self, SYS_RES_IRQ, &rid,
39, 39, 1, RF_SHAREABLE | RF_ACTIVE);
if (sc->irq_res == NULL) {
device_printf(self, "Could not allocate irq\n");
ehci_xls_detach(self);
return ENXIO;
}
sc->sc_bus.bdev = device_add_child(self, "usb", -1);
if (!sc->sc_bus.bdev) {
device_printf(self, "Could not add USB device\n");
ehci_xls_detach(self);
return ENOMEM;
}
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
/* ehci_pci_match will never return NULL if ehci_pci_probe succeeded */
device_set_desc(sc->sc_bus.bdev, xlr_usb_dev_desc);
sprintf(sc->sc_vendor, xlr_vendor_desc);
err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
(driver_intr_t *) ehci_intr, sc, &sc->ih);
if (err) {
device_printf(self, "Could not setup irq, %d\n", err);
sc->ih = NULL;
ehci_xls_detach(self);
return ENXIO;
}
/*
* Find companion controllers. According to the spec they always
* have lower function numbers so they should be enumerated already.
*/
parent = device_get_parent(self);
res = device_get_children(parent, &neighbors, &count);
if (res != 0) {
device_printf(self, "Error finding companion busses\n");
ehci_xls_detach(self);
return ENXIO;
}
sc->sc_ncomp = 0;
ehci_xls_takecontroller(self);
err = ehci_init(sc);
if (!err) {
sc->sc_flags |= EHCI_SCFLG_DONEINIT;
err = device_probe_and_attach(sc->sc_bus.bdev);
}
if (err) {
device_printf(self, "USB init failed err=%d\n", err);
ehci_xls_detach(self);
return EIO;
}
return 0;
}
static int
ehci_xls_detach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
ehci_detach(sc, 0);
sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
}
/*
* disable interrupts that might have been switched on in ehci_init
*/
if (sc->iot && sc->ioh)
bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0);
if (sc->irq_res && sc->ih) {
int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
if (err)
/* XXX or should we panic? */
device_printf(self, "Could not tear down irq, %d\n",
err);
sc->ih = NULL;
}
if (sc->sc_bus.bdev) {
device_delete_child(self, sc->sc_bus.bdev);
sc->sc_bus.bdev = NULL;
}
if (sc->irq_res) {
bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
sc->irq_res = NULL;
}
if (sc->io_res) {
bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM, sc->io_res);
sc->io_res = NULL;
sc->iot = 0;
sc->ioh = 0;
}
return 0;
}
static void
ehci_xls_takecontroller(device_t self)
{
//device_printf(self, "In func %s\n", __func__);
}
static void
ehci_xls_givecontroller(device_t self)
{
//device_printf(self, "In func %s\n", __func__);
}
static device_method_t ehci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ehci_xls_probe),
DEVMETHOD(device_attach, ehci_xls_attach),
DEVMETHOD(device_detach, ehci_xls_detach),
DEVMETHOD(device_suspend, ehci_xls_suspend),
DEVMETHOD(device_resume, ehci_xls_resume),
DEVMETHOD(device_shutdown, ehci_xls_shutdown),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
{0, 0}
};
static driver_t ehci_driver = {
"ehci",
ehci_methods,
sizeof(ehci_softc_t),
};
static devclass_t ehci_devclass;
DRIVER_MODULE(ehci, iodi, ehci_driver, ehci_devclass, 0, 0);
/* DRIVER_MODULE(ehci, cardbus, ehci_driver, ehci_devclass, 0, 0); */