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:
parent
022e93cf87
commit
257c916acf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/mips/; revision=198160
sys/mips/rmi
Makefile.msgringboard.cboard.hclock.cclock.hdebug.hinterrupt.hiodi.ciomap.hmsgring.cmsgring.cfgmsgring.hmsgring_xls.cmsgring_xls.cfgon_chip.cpcibus.cpcibus.hperfmon.hperfmon_kern.cperfmon_percpu.cperfmon_utils.hperfmon_xlrconfig.hpic.hshared_structs.hshared_structs_func.hshared_structs_offsets.huart_bus_xlr_iodi.cuart_cpu_mips_xlr.cxlr_boot1_console.cxlr_csum_nocopy.Sxlr_i2c.cxlr_machdep.cxlr_pci.cxlrconfig.hxls_ehci.c
14
sys/mips/rmi/Makefile.msgring
Normal file
14
sys/mips/rmi/Makefile.msgring
Normal 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
178
sys/mips/rmi/board.c
Normal 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
275
sys/mips/rmi/board.h
Normal 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
213
sys/mips/rmi/clock.c
Normal 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
40
sys/mips/rmi/clock.h
Normal 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
103
sys/mips/rmi/debug.h
Executable 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
43
sys/mips/rmi/interrupt.h
Normal 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
272
sys/mips/rmi/iodi.c
Normal 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
110
sys/mips/rmi/iomap.h
Normal 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
318
sys/mips/rmi/msgring.c
Normal 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
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
507
sys/mips/rmi/msgring.h
Executable 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
218
sys/mips/rmi/msgring_xls.c
Normal 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
563
sys/mips/rmi/msgring_xls.cfg
Executable 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
313
sys/mips/rmi/on_chip.c
Normal 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
328
sys/mips/rmi/pcibus.c
Normal 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
49
sys/mips/rmi/pcibus.h
Normal 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
168
sys/mips/rmi/perfmon.h
Normal 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
162
sys/mips/rmi/perfmon_kern.c
Normal 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");
|
||||
|
299
sys/mips/rmi/perfmon_percpu.c
Normal file
299
sys/mips/rmi/perfmon_percpu.c
Normal 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 ;
|
||||
}
|
113
sys/mips/rmi/perfmon_utils.h
Normal file
113
sys/mips/rmi/perfmon_utils.h
Normal 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
|
156
sys/mips/rmi/perfmon_xlrconfig.h
Normal file
156
sys/mips/rmi/perfmon_xlrconfig.h
Normal 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
257
sys/mips/rmi/pic.h
Normal 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
108
sys/mips/rmi/shared_structs.h
Executable 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
|
54
sys/mips/rmi/shared_structs_func.h
Executable file
54
sys/mips/rmi/shared_structs_func.h
Executable 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
|
76
sys/mips/rmi/shared_structs_offsets.h
Executable file
76
sys/mips/rmi/shared_structs_offsets.h
Executable 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
|
73
sys/mips/rmi/uart_bus_xlr_iodi.c
Normal file
73
sys/mips/rmi/uart_bus_xlr_iodi.c
Normal 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);
|
171
sys/mips/rmi/uart_cpu_mips_xlr.c
Normal file
171
sys/mips/rmi/uart_cpu_mips_xlr.c
Normal 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);
|
||||
|
113
sys/mips/rmi/xlr_boot1_console.c
Normal file
113
sys/mips/rmi/xlr_boot1_console.c
Normal 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
|
217
sys/mips/rmi/xlr_csum_nocopy.S
Normal file
217
sys/mips/rmi/xlr_csum_nocopy.S
Normal 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
442
sys/mips/rmi/xlr_i2c.c
Normal 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
650
sys/mips/rmi/xlr_machdep.c
Normal 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
410
sys/mips/rmi/xlr_pci.c
Normal 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
327
sys/mips/rmi/xlrconfig.h
Normal 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
305
sys/mips/rmi/xls_ehci.c
Normal 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); */
|
Loading…
Reference in New Issue
Block a user