Merge from projects/mips to head by hand:
Copy over the support files (except sys/conf and sys/mips/conf) for RMI XLR processor support. This port has been contributed by RMI and brought up to date by Randal Stewart (rrs@). This port is a work in progress, and there might still be significant changes. The port makes it to multi-user, but is still early beta.
This commit is contained in:
commit
6e9fd5e257
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=201917
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*
|
180
sys/mips/rmi/board.c
Normal file
180
sys/mips/rmi/board.c
Normal file
@ -0,0 +1,180 @@
|
||||
/*********************************************************************
|
||||
*
|
||||
* Copyright 2003-2006 Raza Microelectronics, Inc. (RMI). All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Raza Microelectronics, Inc. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RMI OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************RMI_2**********************************/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
#include <machine/cpufunc.h>
|
||||
#include <mips/rmi/msgring.h>
|
||||
#include <mips/rmi/board.h>
|
||||
#include <mips/rmi/pic.h>
|
||||
#include <mips/rmi/shared_structs.h>
|
||||
|
||||
static int xlr_rxstn_to_txstn_map[128] = {
|
||||
[0 ... 7] = TX_STN_CPU_0,
|
||||
[8 ... 15] = TX_STN_CPU_1,
|
||||
[16 ... 23] = TX_STN_CPU_2,
|
||||
[24 ... 31] = TX_STN_CPU_3,
|
||||
[32 ... 39] = TX_STN_CPU_4,
|
||||
[40 ... 47] = TX_STN_CPU_5,
|
||||
[48 ... 55] = TX_STN_CPU_6,
|
||||
[56 ... 63] = TX_STN_CPU_7,
|
||||
[64 ... 95] = TX_STN_INVALID,
|
||||
[96 ... 103] = TX_STN_GMAC,
|
||||
[104 ... 107] = TX_STN_DMA,
|
||||
[108 ... 111] = TX_STN_INVALID,
|
||||
[112 ... 113] = TX_STN_XGS_0,
|
||||
[114 ... 115] = TX_STN_XGS_1,
|
||||
[116 ... 119] = TX_STN_INVALID,
|
||||
[120 ... 127] = TX_STN_SAE
|
||||
};
|
||||
|
||||
static int xls_rxstn_to_txstn_map[128] = {
|
||||
[0 ... 7] = TX_STN_CPU_0,
|
||||
[8 ... 15] = TX_STN_CPU_1,
|
||||
[16 ... 23] = TX_STN_CPU_2,
|
||||
[24 ... 31] = TX_STN_CPU_3,
|
||||
[32 ... 63] = TX_STN_INVALID,
|
||||
[64 ... 71] = TX_STN_PCIE,
|
||||
[72 ... 79] = TX_STN_INVALID,
|
||||
[80 ... 87] = TX_STN_GMAC1,
|
||||
[88 ... 95] = TX_STN_INVALID,
|
||||
[96 ... 103] = TX_STN_GMAC0,
|
||||
[104 ... 107] = TX_STN_DMA,
|
||||
[108 ... 111] = TX_STN_CDE,
|
||||
[112 ... 119] = TX_STN_INVALID,
|
||||
[120 ... 127] = TX_STN_SAE
|
||||
};
|
||||
|
||||
struct stn_cc *xlr_core_cc_configs[] = {&cc_table_cpu_0, &cc_table_cpu_1,
|
||||
&cc_table_cpu_2, &cc_table_cpu_3,
|
||||
&cc_table_cpu_4, &cc_table_cpu_5,
|
||||
&cc_table_cpu_6, &cc_table_cpu_7};
|
||||
|
||||
struct stn_cc *xls_core_cc_configs[] = {&xls_cc_table_cpu_0, &xls_cc_table_cpu_1,
|
||||
&xls_cc_table_cpu_2, &xls_cc_table_cpu_3};
|
||||
|
||||
struct xlr_board_info xlr_board_info;
|
||||
|
||||
/*
|
||||
* All our knowledge of chip and board that cannot be detected by probing
|
||||
* at run-time goes here
|
||||
*/
|
||||
int
|
||||
xlr_board_info_setup()
|
||||
{
|
||||
if (xlr_is_xls()) {
|
||||
xlr_board_info.is_xls = 1;
|
||||
xlr_board_info.nr_cpus = 8;
|
||||
xlr_board_info.usb = 1;
|
||||
xlr_board_info.cfi =
|
||||
(xlr_boot1_info.board_major_version != RMI_XLR_BOARD_ARIZONA_VIII);
|
||||
xlr_board_info.pci_irq = 0;
|
||||
xlr_board_info.credit_configs = xls_core_cc_configs;
|
||||
xlr_board_info.bucket_sizes = &xls_bucket_sizes;
|
||||
xlr_board_info.msgmap = xls_rxstn_to_txstn_map;
|
||||
xlr_board_info.gmacports = 8;
|
||||
|
||||
/* network block 0 */
|
||||
xlr_board_info.gmac_block[0].type = XLR_GMAC;
|
||||
xlr_board_info.gmac_block[0].enabled = 0xf;
|
||||
xlr_board_info.gmac_block[0].credit_config = &xls_cc_table_gmac0;
|
||||
xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0;
|
||||
xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0;
|
||||
if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI)
|
||||
xlr_board_info.gmac_block[0].mode = XLR_PORT0_RGMII;
|
||||
else
|
||||
xlr_board_info.gmac_block[0].mode = XLR_SGMII;
|
||||
xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET;
|
||||
xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ;
|
||||
xlr_board_info.gmac_block[0].baseinst = 0;
|
||||
|
||||
/* network block 1 */
|
||||
xlr_board_info.gmac_block[1].type = XLR_GMAC;
|
||||
xlr_board_info.gmac_block[1].enabled = 0xf;
|
||||
xlr_board_info.gmac_block[1].credit_config = &xls_cc_table_gmac1;
|
||||
xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_GMAC1_TX0;
|
||||
xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_GMAC1_FR_0;
|
||||
xlr_board_info.gmac_block[1].mode = XLR_SGMII;
|
||||
xlr_board_info.gmac_block[1].baseaddr = XLR_IO_GMAC_4_OFFSET;
|
||||
xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ;
|
||||
xlr_board_info.gmac_block[1].baseinst = 4;
|
||||
|
||||
/* network block 2 */
|
||||
xlr_board_info.gmac_block[2].enabled = 0; /* disabled on XLS */
|
||||
} else {
|
||||
xlr_board_info.is_xls = 0;
|
||||
xlr_board_info.nr_cpus = 32;
|
||||
xlr_board_info.usb = 0;
|
||||
xlr_board_info.cfi = 1;
|
||||
xlr_board_info.pci_irq = 0;
|
||||
xlr_board_info.credit_configs = xlr_core_cc_configs;
|
||||
xlr_board_info.bucket_sizes = &bucket_sizes;
|
||||
xlr_board_info.msgmap = xlr_rxstn_to_txstn_map;
|
||||
xlr_board_info.gmacports = 4;
|
||||
|
||||
/* GMAC0 */
|
||||
xlr_board_info.gmac_block[0].type = XLR_GMAC;
|
||||
xlr_board_info.gmac_block[0].enabled = 0xf;
|
||||
xlr_board_info.gmac_block[0].credit_config = &cc_table_gmac;
|
||||
xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0;
|
||||
xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0;
|
||||
xlr_board_info.gmac_block[0].mode = XLR_RGMII;
|
||||
xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET;
|
||||
xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ;
|
||||
xlr_board_info.gmac_block[0].baseinst = 0;
|
||||
|
||||
/* XGMAC0 */
|
||||
xlr_board_info.gmac_block[1].type = XLR_XGMAC;
|
||||
xlr_board_info.gmac_block[1].enabled = 1;
|
||||
xlr_board_info.gmac_block[1].credit_config = &cc_table_xgs_0;
|
||||
xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_XGS0_TX;
|
||||
xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_XGS0FR;
|
||||
xlr_board_info.gmac_block[1].mode = -1;
|
||||
xlr_board_info.gmac_block[1].baseaddr = XLR_IO_XGMAC_0_OFFSET;
|
||||
xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ;
|
||||
xlr_board_info.gmac_block[1].baseinst = 4;
|
||||
|
||||
/* XGMAC1 */
|
||||
xlr_board_info.gmac_block[2].type = XLR_XGMAC;
|
||||
xlr_board_info.gmac_block[2].enabled = 1;
|
||||
xlr_board_info.gmac_block[2].credit_config = &cc_table_xgs_1;
|
||||
xlr_board_info.gmac_block[2].station_txbase = MSGRNG_STNID_XGS1_TX;
|
||||
xlr_board_info.gmac_block[2].station_rfr = MSGRNG_STNID_XGS1FR;
|
||||
xlr_board_info.gmac_block[2].mode = -1;
|
||||
xlr_board_info.gmac_block[2].baseaddr = XLR_IO_XGMAC_1_OFFSET;
|
||||
xlr_board_info.gmac_block[2].baseirq = PIC_XGS_1_IRQ;
|
||||
xlr_board_info.gmac_block[2].baseinst = 5;
|
||||
}
|
||||
return 0;
|
||||
}
|
282
sys/mips/rmi/board.h
Normal file
282
sys/mips/rmi/board.h
Normal file
@ -0,0 +1,282 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
#ifndef _RMI_BOARD_H_
|
||||
#define _RMI_BOARD_H_
|
||||
|
||||
#define RMI_XLR_BOARD_ARIZONA_I 1
|
||||
#define RMI_XLR_BOARD_ARIZONA_II 2
|
||||
#define RMI_XLR_BOARD_ARIZONA_III 3
|
||||
#define RMI_XLR_BOARD_ARIZONA_IV 4
|
||||
#define RMI_XLR_BOARD_ARIZONA_V 5
|
||||
#define RMI_XLR_BOARD_ARIZONA_VI 6
|
||||
#define RMI_XLR_BOARD_ARIZONA_VII 7
|
||||
#define RMI_XLR_BOARD_ARIZONA_VIII 8
|
||||
|
||||
#define RMI_CHIP_XLR308_A0 0x0c0600
|
||||
#define RMI_CHIP_XLR508_A0 0x0c0700
|
||||
#define RMI_CHIP_XLR516_A0 0x0c0800
|
||||
#define RMI_CHIP_XLR532_A0 0x0c0900
|
||||
#define RMI_CHIP_XLR716_A0 0x0c0a00
|
||||
#define RMI_CHIP_XLR732_A0 0x0c0b00
|
||||
|
||||
#define RMI_CHIP_XLR308_A1 0x0c0601
|
||||
#define RMI_CHIP_XLR508_A1 0x0c0701
|
||||
#define RMI_CHIP_XLR516_A1 0x0c0801
|
||||
#define RMI_CHIP_XLR532_A1 0x0c0901
|
||||
#define RMI_CHIP_XLR716_A1 0x0c0a01
|
||||
#define RMI_CHIP_XLR732_A1 0x0c0b01
|
||||
|
||||
#define RMI_CHIP_XLR308_B0 0x0c0602
|
||||
#define RMI_CHIP_XLR508_B0 0x0c0702
|
||||
#define RMI_CHIP_XLR516_B0 0x0c0802
|
||||
#define RMI_CHIP_XLR532_B0 0x0c0902
|
||||
#define RMI_CHIP_XLR716_B0 0x0c0a02
|
||||
#define RMI_CHIP_XLR732_B0 0x0c0b02
|
||||
|
||||
#define RMI_CHIP_XLR308_B1 0x0c0603
|
||||
#define RMI_CHIP_XLR508_B1 0x0c0703
|
||||
#define RMI_CHIP_XLR516_B1 0x0c0803
|
||||
#define RMI_CHIP_XLR532_B1 0x0c0903
|
||||
#define RMI_CHIP_XLR716_B1 0x0c0a03
|
||||
#define RMI_CHIP_XLR732_B1 0x0c0b03
|
||||
|
||||
#define RMI_CHIP_XLR308_B2 0x0c0604
|
||||
#define RMI_CHIP_XLR508_B2 0x0c0704
|
||||
#define RMI_CHIP_XLR516_B2 0x0c0804
|
||||
#define RMI_CHIP_XLR532_B2 0x0c0904
|
||||
#define RMI_CHIP_XLR716_B2 0x0c0a04
|
||||
#define RMI_CHIP_XLR732_B2 0x0c0b04
|
||||
|
||||
#define RMI_CHIP_XLR308_C0 0x0c0705
|
||||
#define RMI_CHIP_XLR508_C0 0x0c0b05
|
||||
#define RMI_CHIP_XLR516_C0 0x0c0a05
|
||||
#define RMI_CHIP_XLR532_C0 0x0c0805
|
||||
#define RMI_CHIP_XLR716_C0 0x0c0205
|
||||
#define RMI_CHIP_XLR732_C0 0x0c0005
|
||||
|
||||
#define RMI_CHIP_XLR308_C1 0x0c0706
|
||||
#define RMI_CHIP_XLR508_C1 0x0c0b06
|
||||
#define RMI_CHIP_XLR516_C1 0x0c0a06
|
||||
#define RMI_CHIP_XLR532_C1 0x0c0806
|
||||
#define RMI_CHIP_XLR716_C1 0x0c0206
|
||||
#define RMI_CHIP_XLR732_C1 0x0c0006
|
||||
|
||||
#define RMI_CHIP_XLR308_C2 0x0c0707
|
||||
#define RMI_CHIP_XLR508_C2 0x0c0b07
|
||||
#define RMI_CHIP_XLR516_C2 0x0c0a07
|
||||
#define RMI_CHIP_XLR532_C2 0x0c0807
|
||||
#define RMI_CHIP_XLR716_C2 0x0c0207
|
||||
#define RMI_CHIP_XLR732_C2 0x0c0007
|
||||
|
||||
#define RMI_CHIP_XLR308_C3 0x0c0708
|
||||
#define RMI_CHIP_XLR508_C3 0x0c0b08
|
||||
#define RMI_CHIP_XLR516_C3 0x0c0a08
|
||||
#define RMI_CHIP_XLR532_C3 0x0c0808
|
||||
#define RMI_CHIP_XLR716_C3 0x0c0208
|
||||
#define RMI_CHIP_XLR732_C3 0x0c0008
|
||||
|
||||
#define RMI_CHIP_XLR308_C4 0x0c0709
|
||||
#define RMI_CHIP_XLR508_C4 0x0c0b09
|
||||
#define RMI_CHIP_XLR516_C4 0x0c0a09
|
||||
#define RMI_CHIP_XLR532_C4 0x0c0809
|
||||
#define RMI_CHIP_XLR716_C4 0x0c0209
|
||||
#define RMI_CHIP_XLR732_C4 0x0c0009
|
||||
|
||||
#define RMI_CHIP_XLS608_A0 0x0c8000
|
||||
#define RMI_CHIP_XLS408_A0 0x0c8800
|
||||
#define RMI_CHIP_XLS404_A0 0x0c8c00
|
||||
#define RMI_CHIP_XLS208_A0 0x0c8e00
|
||||
#define RMI_CHIP_XLS204_A0 0x0c8f00
|
||||
|
||||
#define RMI_CHIP_XLS608_A1 0x0c8001
|
||||
#define RMI_CHIP_XLS408_A1 0x0c8801
|
||||
#define RMI_CHIP_XLS404_A1 0x0c8c01
|
||||
#define RMI_CHIP_XLS208_A1 0x0c8e01
|
||||
#define RMI_CHIP_XLS204_A1 0x0c8f01
|
||||
|
||||
static __inline__ unsigned int
|
||||
xlr_revision(void)
|
||||
{
|
||||
return mips_rd_prid() & 0xff00ff;
|
||||
}
|
||||
|
||||
static __inline__ unsigned int
|
||||
xlr_is_xls(void)
|
||||
{
|
||||
uint32_t prid = mips_rd_prid();
|
||||
|
||||
return (prid & 0xf000) == 0x8000 || (prid & 0xf000) == 0x4000;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_revision_a0(void)
|
||||
{
|
||||
return xlr_revision() == 0x0c0000;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_revision_b0(void)
|
||||
{
|
||||
return xlr_revision() == 0x0c0002;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_revision_b1(void)
|
||||
{
|
||||
return xlr_revision() == 0x0c0003;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_board_atx_i(void)
|
||||
{
|
||||
return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_I;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_board_atx_ii(void)
|
||||
{
|
||||
return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_II;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_board_atx_ii_b(void)
|
||||
{
|
||||
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_II)
|
||||
&& (xlr_boot1_info.board_minor_version == 1);
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_board_atx_iii(void)
|
||||
{
|
||||
return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_board_atx_iv(void)
|
||||
{
|
||||
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_IV)
|
||||
&& (xlr_boot1_info.board_minor_version == 0);
|
||||
}
|
||||
static __inline__ int
|
||||
xlr_board_atx_iv_b(void)
|
||||
{
|
||||
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_IV)
|
||||
&& (xlr_boot1_info.board_minor_version == 1);
|
||||
}
|
||||
static __inline__ int
|
||||
xlr_board_atx_v(void)
|
||||
{
|
||||
return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_V;
|
||||
}
|
||||
static __inline__ int
|
||||
xlr_board_atx_vi(void)
|
||||
{
|
||||
return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_board_atx_iii_256(void)
|
||||
{
|
||||
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III)
|
||||
&& (xlr_boot1_info.board_minor_version == 0);
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_board_atx_iii_512(void)
|
||||
{
|
||||
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III)
|
||||
&& (xlr_boot1_info.board_minor_version == 1);
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_board_atx_v_512(void)
|
||||
{
|
||||
return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_V)
|
||||
&& (xlr_boot1_info.board_minor_version == 1);
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_board_pci(void)
|
||||
{
|
||||
return (xlr_board_atx_iii_256() || xlr_board_atx_iii_512()
|
||||
|| xlr_board_atx_v_512());
|
||||
}
|
||||
static __inline__ int
|
||||
xlr_is_xls2xx(void)
|
||||
{
|
||||
uint32_t chipid = mips_rd_prid() & 0xffffff00U;
|
||||
|
||||
return chipid == 0x0c8e00 || chipid == 0x0c8f00;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_is_xls4xx(void)
|
||||
{
|
||||
uint32_t chipid = mips_rd_prid() & 0xffffff00U;
|
||||
|
||||
return chipid == 0x0c8800 || chipid == 0x0c8c00;
|
||||
}
|
||||
|
||||
/* all our knowledge of chip and board that cannot be detected run-time goes here */
|
||||
enum gmac_block_types {
|
||||
XLR_GMAC, XLR_XGMAC, XLR_SPI4
|
||||
};
|
||||
enum gmac_block_modes {
|
||||
XLR_RGMII, XLR_SGMII, XLR_PORT0_RGMII
|
||||
};
|
||||
struct xlr_board_info {
|
||||
int is_xls;
|
||||
int nr_cpus;
|
||||
int usb; /* usb enabled ? */
|
||||
int cfi; /* compact flash driver for NOR? */
|
||||
int pci_irq;
|
||||
struct stn_cc **credit_configs; /* pointer to Core station credits */
|
||||
struct bucket_size *bucket_sizes; /* pointer to Core station
|
||||
* bucket */
|
||||
int *msgmap; /* mapping of message station to devices */
|
||||
int gmacports; /* number of gmac ports on the board */
|
||||
struct xlr_gmac_block_t {
|
||||
int type; /* see enum gmac_block_types */
|
||||
unsigned int enabled; /* mask of ports enabled */
|
||||
struct stn_cc *credit_config; /* credit configuration */
|
||||
int station_txbase; /* station id for tx */
|
||||
int station_rfr;/* free desc bucket */
|
||||
int mode; /* see gmac_block_modes */
|
||||
uint32_t baseaddr; /* IO base */
|
||||
int baseirq; /* first irq for this block, the rest are in
|
||||
* sequence */
|
||||
int baseinst; /* the first rge unit for this block */
|
||||
} gmac_block[3];
|
||||
};
|
||||
|
||||
extern struct xlr_board_info xlr_board_info;
|
||||
int xlr_board_info_setup(void);
|
||||
|
||||
#endif
|
831
sys/mips/rmi/bus_space_rmi.c
Normal file
831
sys/mips/rmi/bus_space_rmi.c
Normal file
@ -0,0 +1,831 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/ktr.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/cache.h>
|
||||
void xlr_print_int(uint32_t);
|
||||
|
||||
static int
|
||||
rmi_bus_space_map(void *t, bus_addr_t addr,
|
||||
bus_size_t size, int flags,
|
||||
bus_space_handle_t * bshp);
|
||||
|
||||
|
||||
static void
|
||||
rmi_bus_space_unmap(void *t, bus_space_handle_t bsh,
|
||||
bus_size_t size);
|
||||
|
||||
static int
|
||||
rmi_bus_space_subregion(void *t,
|
||||
bus_space_handle_t bsh,
|
||||
bus_size_t offset, bus_size_t size,
|
||||
bus_space_handle_t * nbshp);
|
||||
|
||||
static u_int8_t
|
||||
rmi_bus_space_read_1(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset);
|
||||
|
||||
static u_int16_t
|
||||
rmi_bus_space_read_2(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset);
|
||||
|
||||
static u_int32_t
|
||||
rmi_bus_space_read_4(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset);
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_multi_1(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int8_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_multi_2(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int16_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_multi_4(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int32_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_region_1(void *t,
|
||||
bus_space_handle_t bsh,
|
||||
bus_size_t offset, u_int8_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_region_2(void *t,
|
||||
bus_space_handle_t bsh,
|
||||
bus_size_t offset, u_int16_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_region_4(void *t,
|
||||
bus_space_handle_t bsh,
|
||||
bus_size_t offset, u_int32_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_1(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int8_t value);
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_2(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int16_t value);
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_4(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int32_t value);
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_multi_1(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset,
|
||||
const u_int8_t * addr,
|
||||
size_t count);
|
||||
static void
|
||||
rmi_bus_space_write_multi_2(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset,
|
||||
const u_int16_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_multi_4(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset,
|
||||
const u_int32_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_region_2(void *t,
|
||||
bus_space_handle_t bsh,
|
||||
bus_size_t offset,
|
||||
const u_int16_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_region_4(void *t,
|
||||
bus_space_handle_t bsh,
|
||||
bus_size_t offset,
|
||||
const u_int32_t * addr,
|
||||
size_t count);
|
||||
|
||||
|
||||
static void
|
||||
rmi_bus_space_set_region_2(void *t,
|
||||
bus_space_handle_t bsh,
|
||||
bus_size_t offset, u_int16_t value,
|
||||
size_t count);
|
||||
static void
|
||||
rmi_bus_space_set_region_4(void *t,
|
||||
bus_space_handle_t bsh,
|
||||
bus_size_t offset, u_int32_t value,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused,
|
||||
bus_size_t offset __unused, bus_size_t len __unused, int flags);
|
||||
|
||||
|
||||
static void
|
||||
rmi_bus_space_copy_region_2(void *t,
|
||||
bus_space_handle_t bsh1,
|
||||
bus_size_t off1,
|
||||
bus_space_handle_t bsh2,
|
||||
bus_size_t off2, size_t count);
|
||||
|
||||
u_int8_t
|
||||
rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle,
|
||||
bus_size_t offset);
|
||||
|
||||
static u_int16_t
|
||||
rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle,
|
||||
bus_size_t offset);
|
||||
|
||||
static u_int32_t
|
||||
rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle,
|
||||
bus_size_t offset);
|
||||
static void
|
||||
rmi_bus_space_read_multi_stream_1(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int8_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_multi_stream_2(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int16_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_multi_stream_4(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int32_t * addr,
|
||||
size_t count);
|
||||
|
||||
void
|
||||
rmi_bus_space_write_stream_1(void *t, bus_space_handle_t bsh,
|
||||
bus_size_t offset, u_int8_t value);
|
||||
static void
|
||||
rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int16_t value);
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int32_t value);
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_multi_stream_1(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset,
|
||||
const u_int8_t * addr,
|
||||
size_t count);
|
||||
static void
|
||||
rmi_bus_space_write_multi_stream_2(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset,
|
||||
const u_int16_t * addr,
|
||||
size_t count);
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_multi_stream_4(void *t,
|
||||
bus_space_handle_t handle,
|
||||
bus_size_t offset,
|
||||
const u_int32_t * addr,
|
||||
size_t count);
|
||||
|
||||
|
||||
static struct bus_space local_rmi_bus_space = {
|
||||
/* cookie */
|
||||
(void *)0,
|
||||
|
||||
/* mapping/unmapping */
|
||||
rmi_bus_space_map,
|
||||
rmi_bus_space_unmap,
|
||||
rmi_bus_space_subregion,
|
||||
|
||||
/* allocation/deallocation */
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
/* barrier */
|
||||
rmi_bus_space_barrier,
|
||||
|
||||
/* read (single) */
|
||||
rmi_bus_space_read_1,
|
||||
rmi_bus_space_read_2,
|
||||
rmi_bus_space_read_4,
|
||||
NULL,
|
||||
|
||||
/* read multiple */
|
||||
rmi_bus_space_read_multi_1,
|
||||
rmi_bus_space_read_multi_2,
|
||||
rmi_bus_space_read_multi_4,
|
||||
NULL,
|
||||
|
||||
/* read region */
|
||||
rmi_bus_space_read_region_1,
|
||||
rmi_bus_space_read_region_2,
|
||||
rmi_bus_space_read_region_4,
|
||||
NULL,
|
||||
|
||||
/* write (single) */
|
||||
rmi_bus_space_write_1,
|
||||
rmi_bus_space_write_2,
|
||||
rmi_bus_space_write_4,
|
||||
NULL,
|
||||
|
||||
/* write multiple */
|
||||
rmi_bus_space_write_multi_1,
|
||||
rmi_bus_space_write_multi_2,
|
||||
rmi_bus_space_write_multi_4,
|
||||
NULL,
|
||||
|
||||
/* write region */
|
||||
NULL,
|
||||
rmi_bus_space_write_region_2,
|
||||
rmi_bus_space_write_region_4,
|
||||
NULL,
|
||||
|
||||
/* set multiple */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
/* set region */
|
||||
NULL,
|
||||
rmi_bus_space_set_region_2,
|
||||
rmi_bus_space_set_region_4,
|
||||
NULL,
|
||||
|
||||
/* copy */
|
||||
NULL,
|
||||
rmi_bus_space_copy_region_2,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
/* read (single) stream */
|
||||
rmi_bus_space_read_stream_1,
|
||||
rmi_bus_space_read_stream_2,
|
||||
rmi_bus_space_read_stream_4,
|
||||
NULL,
|
||||
|
||||
/* read multiple stream */
|
||||
rmi_bus_space_read_multi_stream_1,
|
||||
rmi_bus_space_read_multi_stream_2,
|
||||
rmi_bus_space_read_multi_stream_4,
|
||||
NULL,
|
||||
|
||||
/* read region stream */
|
||||
rmi_bus_space_read_region_1,
|
||||
rmi_bus_space_read_region_2,
|
||||
rmi_bus_space_read_region_4,
|
||||
NULL,
|
||||
|
||||
/* write (single) stream */
|
||||
rmi_bus_space_write_stream_1,
|
||||
rmi_bus_space_write_stream_2,
|
||||
rmi_bus_space_write_stream_4,
|
||||
NULL,
|
||||
|
||||
/* write multiple stream */
|
||||
rmi_bus_space_write_multi_stream_1,
|
||||
rmi_bus_space_write_multi_stream_2,
|
||||
rmi_bus_space_write_multi_stream_4,
|
||||
NULL,
|
||||
|
||||
/* write region stream */
|
||||
NULL,
|
||||
rmi_bus_space_write_region_2,
|
||||
rmi_bus_space_write_region_4,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* generic bus_space tag */
|
||||
bus_space_tag_t rmi_bus_space = &local_rmi_bus_space;
|
||||
|
||||
#define MIPS_BUS_SPACE_IO 0 /* space is i/o space */
|
||||
#define MIPS_BUS_SPACE_MEM 1 /* space is mem space */
|
||||
#define MIPS_BUS_SPACE_PCI 10 /* avoid conflict with other spaces */
|
||||
|
||||
#define BUS_SPACE_UNRESTRICTED (~0)
|
||||
|
||||
#define SWAP32(x)\
|
||||
(((x) & 0xff000000) >> 24) | \
|
||||
(((x) & 0x000000ff) << 24) | \
|
||||
(((x) & 0x0000ff00) << 8) | \
|
||||
(((x) & 0x00ff0000) >> 8)
|
||||
|
||||
#define SWAP16(x)\
|
||||
(((x) & 0xff00) >> 8) | \
|
||||
(((x) & 0x00ff) << 8)
|
||||
|
||||
/*
|
||||
* Map a region of device bus space into CPU virtual address space.
|
||||
*/
|
||||
|
||||
|
||||
static int
|
||||
rmi_bus_space_map(void *t __unused, bus_addr_t addr,
|
||||
bus_size_t size __unused, int flags __unused,
|
||||
bus_space_handle_t * bshp)
|
||||
{
|
||||
|
||||
*bshp = addr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unmap a region of device bus space.
|
||||
*/
|
||||
static void
|
||||
rmi_bus_space_unmap(void *t __unused, bus_space_handle_t bsh __unused,
|
||||
bus_size_t size __unused)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a new handle for a subregion of an already-mapped area of bus space.
|
||||
*/
|
||||
|
||||
static int
|
||||
rmi_bus_space_subregion(void *t __unused, bus_space_handle_t bsh,
|
||||
bus_size_t offset, bus_size_t size __unused,
|
||||
bus_space_handle_t * nbshp)
|
||||
{
|
||||
*nbshp = bsh + offset;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 1, 2, 4, or 8 byte quantity from bus space
|
||||
* described by tag/handle/offset.
|
||||
*/
|
||||
|
||||
static u_int8_t
|
||||
rmi_bus_space_read_1(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset)
|
||||
{
|
||||
if ((int)tag == MIPS_BUS_SPACE_PCI)
|
||||
return (u_int8_t) (*(volatile u_int8_t *)(handle + offset));
|
||||
else
|
||||
return (u_int8_t) (*(volatile u_int32_t *)(handle + offset));
|
||||
}
|
||||
|
||||
static u_int16_t
|
||||
rmi_bus_space_read_2(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset)
|
||||
{
|
||||
if ((int)tag == MIPS_BUS_SPACE_PCI)
|
||||
return SWAP16((u_int16_t) (*(volatile u_int16_t *)(handle + offset)));
|
||||
else
|
||||
return *(volatile u_int16_t *)(handle + offset);
|
||||
}
|
||||
|
||||
static u_int32_t
|
||||
rmi_bus_space_read_4(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset)
|
||||
{
|
||||
if ((int)tag == MIPS_BUS_SPACE_PCI)
|
||||
return SWAP32((*(volatile u_int32_t *)(handle + offset)));
|
||||
else
|
||||
return (*(volatile u_int32_t *)(handle + offset));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Read `count' 1, 2, 4, or 8 byte quantities from bus space
|
||||
* described by tag/handle/offset and copy into buffer provided.
|
||||
*/
|
||||
static void
|
||||
rmi_bus_space_read_multi_1(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int8_t * addr, size_t count)
|
||||
{
|
||||
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
*addr = (*(volatile u_int8_t *)(handle + offset));
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_multi_2(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int16_t * addr, size_t count)
|
||||
{
|
||||
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
*addr = *(volatile u_int16_t *)(handle + offset);
|
||||
*addr = SWAP16(*addr);
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_multi_4(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int32_t * addr, size_t count)
|
||||
{
|
||||
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
*addr = *(volatile u_int32_t *)(handle + offset);
|
||||
*addr = SWAP32(*addr);
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the 1, 2, 4, or 8 byte value `value' to bus space
|
||||
* described by tag/handle/offset.
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_1(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int8_t value)
|
||||
{
|
||||
mips_sync();
|
||||
if ((int)tag == MIPS_BUS_SPACE_PCI)
|
||||
*(volatile u_int8_t *)(handle + offset) = value;
|
||||
else
|
||||
*(volatile u_int32_t *)(handle + offset) = (u_int32_t) value;
|
||||
}
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_2(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int16_t value)
|
||||
{
|
||||
mips_sync();
|
||||
if ((int)tag == MIPS_BUS_SPACE_PCI) {
|
||||
*(volatile u_int16_t *)(handle + offset) = SWAP16(value);
|
||||
} else
|
||||
*(volatile u_int16_t *)(handle + offset) = value;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_4(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int32_t value)
|
||||
{
|
||||
mips_sync();
|
||||
if ((int)tag == MIPS_BUS_SPACE_PCI) {
|
||||
*(volatile u_int32_t *)(handle + offset) = SWAP32(value);
|
||||
} else
|
||||
*(volatile u_int32_t *)(handle + offset) = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Write `count' 1, 2, 4, or 8 byte quantities from the buffer
|
||||
* provided to bus space described by tag/handle/offset.
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_multi_1(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, const u_int8_t * addr, size_t count)
|
||||
{
|
||||
mips_sync();
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
(*(volatile u_int8_t *)(handle + offset)) = *addr;
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_multi_2(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, const u_int16_t * addr, size_t count)
|
||||
{
|
||||
mips_sync();
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
(*(volatile u_int16_t *)(handle + offset)) = SWAP16(*addr);
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_multi_4(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, const u_int32_t * addr, size_t count)
|
||||
{
|
||||
mips_sync();
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
(*(volatile u_int32_t *)(handle + offset)) = SWAP32(*addr);
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
|
||||
* by tag/handle starting at `offset'.
|
||||
*/
|
||||
|
||||
static void
|
||||
rmi_bus_space_set_region_2(void *t, bus_space_handle_t bsh,
|
||||
bus_size_t offset, u_int16_t value, size_t count)
|
||||
{
|
||||
bus_addr_t addr = bsh + offset;
|
||||
|
||||
for (; count != 0; count--, addr += 2)
|
||||
(*(volatile u_int16_t *)(addr)) = value;
|
||||
}
|
||||
|
||||
static void
|
||||
rmi_bus_space_set_region_4(void *t, bus_space_handle_t bsh,
|
||||
bus_size_t offset, u_int32_t value, size_t count)
|
||||
{
|
||||
bus_addr_t addr = bsh + offset;
|
||||
|
||||
for (; count != 0; count--, addr += 4)
|
||||
(*(volatile u_int32_t *)(addr)) = value;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy `count' 1, 2, 4, or 8 byte values from bus space starting
|
||||
* at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
|
||||
*/
|
||||
static void
|
||||
rmi_bus_space_copy_region_2(void *t, bus_space_handle_t bsh1,
|
||||
bus_size_t off1, bus_space_handle_t bsh2,
|
||||
bus_size_t off2, size_t count)
|
||||
{
|
||||
printf("bus_space_copy_region_2 - unimplemented\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Read `count' 1, 2, 4, or 8 byte quantities from bus space
|
||||
* described by tag/handle/offset and copy into buffer provided.
|
||||
*/
|
||||
|
||||
u_int8_t
|
||||
rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle,
|
||||
bus_size_t offset)
|
||||
{
|
||||
|
||||
return *((volatile u_int8_t *)(handle + offset));
|
||||
}
|
||||
|
||||
|
||||
static u_int16_t
|
||||
rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle,
|
||||
bus_size_t offset)
|
||||
{
|
||||
return *(volatile u_int16_t *)(handle + offset);
|
||||
}
|
||||
|
||||
|
||||
static u_int32_t
|
||||
rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle,
|
||||
bus_size_t offset)
|
||||
{
|
||||
return (*(volatile u_int32_t *)(handle + offset));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_multi_stream_1(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int8_t * addr, size_t count)
|
||||
{
|
||||
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
*addr = (*(volatile u_int8_t *)(handle + offset));
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_multi_stream_2(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int16_t * addr, size_t count)
|
||||
{
|
||||
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
*addr = (*(volatile u_int16_t *)(handle + offset));
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rmi_bus_space_read_multi_stream_4(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int32_t * addr, size_t count)
|
||||
{
|
||||
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
*addr = (*(volatile u_int32_t *)(handle + offset));
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Read `count' 1, 2, 4, or 8 byte quantities from bus space
|
||||
* described by tag/handle and starting at `offset' and copy into
|
||||
* buffer provided.
|
||||
*/
|
||||
void
|
||||
rmi_bus_space_read_region_1(void *t, bus_space_handle_t bsh,
|
||||
bus_size_t offset, u_int8_t * addr, size_t count)
|
||||
{
|
||||
bus_addr_t baddr = bsh + offset;
|
||||
|
||||
while (count--) {
|
||||
*addr++ = (*(volatile u_int8_t *)(baddr));
|
||||
baddr += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rmi_bus_space_read_region_2(void *t, bus_space_handle_t bsh,
|
||||
bus_size_t offset, u_int16_t * addr, size_t count)
|
||||
{
|
||||
bus_addr_t baddr = bsh + offset;
|
||||
|
||||
while (count--) {
|
||||
*addr++ = (*(volatile u_int16_t *)(baddr));
|
||||
baddr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rmi_bus_space_read_region_4(void *t, bus_space_handle_t bsh,
|
||||
bus_size_t offset, u_int32_t * addr, size_t count)
|
||||
{
|
||||
bus_addr_t baddr = bsh + offset;
|
||||
|
||||
while (count--) {
|
||||
*addr++ = (*(volatile u_int32_t *)(baddr));
|
||||
baddr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rmi_bus_space_write_stream_1(void *t, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int8_t value)
|
||||
{
|
||||
mips_sync();
|
||||
*(volatile u_int8_t *)(handle + offset) = value;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int16_t value)
|
||||
{
|
||||
mips_sync();
|
||||
*(volatile u_int16_t *)(handle + offset) = value;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle,
|
||||
bus_size_t offset, u_int32_t value)
|
||||
{
|
||||
mips_sync();
|
||||
*(volatile u_int32_t *)(handle + offset) = value;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_multi_stream_1(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, const u_int8_t * addr, size_t count)
|
||||
{
|
||||
mips_sync();
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
(*(volatile u_int8_t *)(handle + offset)) = *addr;
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_multi_stream_2(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, const u_int16_t * addr, size_t count)
|
||||
{
|
||||
mips_sync();
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
(*(volatile u_int16_t *)(handle + offset)) = *addr;
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rmi_bus_space_write_multi_stream_4(void *tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, const u_int32_t * addr, size_t count)
|
||||
{
|
||||
mips_sync();
|
||||
if ((int)tag != MIPS_BUS_SPACE_PCI)
|
||||
return;
|
||||
while (count--) {
|
||||
(*(volatile u_int32_t *)(handle + offset)) = *addr;
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rmi_bus_space_write_region_2(void *t,
|
||||
bus_space_handle_t bsh,
|
||||
bus_size_t offset,
|
||||
const u_int16_t * addr,
|
||||
size_t count)
|
||||
{
|
||||
bus_addr_t baddr = (bus_addr_t) bsh + offset;
|
||||
|
||||
while (count--) {
|
||||
(*(volatile u_int16_t *)(baddr)) = *addr;
|
||||
addr++;
|
||||
baddr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rmi_bus_space_write_region_4(void *t, bus_space_handle_t bsh,
|
||||
bus_size_t offset, const u_int32_t * addr, size_t count)
|
||||
{
|
||||
bus_addr_t baddr = bsh + offset;
|
||||
|
||||
while (count--) {
|
||||
(*(volatile u_int32_t *)(baddr)) = *addr;
|
||||
addr++;
|
||||
baddr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused,
|
||||
bus_size_t offset __unused, bus_size_t len __unused, int flags)
|
||||
{
|
||||
|
||||
}
|
346
sys/mips/rmi/clock.c
Normal file
346
sys/mips/rmi/clock.c
Normal file
@ -0,0 +1,346 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/timetc.h>
|
||||
|
||||
#include <sys/module.h>
|
||||
#include <sys/stdint.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/clock.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/hwfunc.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
|
||||
#include <mips/rmi/iomap.h>
|
||||
#include <mips/rmi/clock.h>
|
||||
#include <mips/rmi/interrupt.h>
|
||||
#include <mips/rmi/pic.h>
|
||||
#include <mips/rmi/shared_structs.h>
|
||||
|
||||
#ifdef XLR_PERFMON
|
||||
#include <mips/rmi/perfmon.h>
|
||||
#endif
|
||||
|
||||
uint64_t counter_freq;
|
||||
uint64_t cycles_per_tick;
|
||||
uint64_t cycles_per_usec;
|
||||
uint64_t cycles_per_sec;
|
||||
uint64_t cycles_per_hz;
|
||||
|
||||
u_int32_t counter_upper = 0;
|
||||
u_int32_t counter_lower_last = 0;
|
||||
|
||||
#define STAT_PROF_CLOCK_SCALE_FACTOR 8
|
||||
|
||||
static int scale_factor;
|
||||
static int count_scale_factor[32];
|
||||
|
||||
uint64_t
|
||||
platform_get_frequency()
|
||||
{
|
||||
return XLR_PIC_HZ;
|
||||
}
|
||||
|
||||
void
|
||||
mips_timer_early_init(uint64_t clock_hz)
|
||||
{
|
||||
/* Initialize clock early so that we can use DELAY sooner */
|
||||
counter_freq = clock_hz;
|
||||
cycles_per_usec = (clock_hz / (1000 * 1000));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* count_compare_clockhandler:
|
||||
*
|
||||
* Handle the clock interrupt when count becomes equal to
|
||||
* compare.
|
||||
*/
|
||||
int
|
||||
count_compare_clockhandler(struct trapframe *tf)
|
||||
{
|
||||
int cpu = PCPU_GET(cpuid);
|
||||
uint32_t cycles;
|
||||
|
||||
critical_enter();
|
||||
|
||||
if (cpu == 0) {
|
||||
mips_wr_compare(0);
|
||||
} else {
|
||||
count_scale_factor[cpu]++;
|
||||
cycles = mips_rd_count();
|
||||
cycles += XLR_CPU_HZ / hz;
|
||||
mips_wr_compare(cycles);
|
||||
|
||||
hardclock_cpu(USERMODE(tf->sr));
|
||||
if (count_scale_factor[cpu] == STAT_PROF_CLOCK_SCALE_FACTOR) {
|
||||
statclock(USERMODE(tf->sr));
|
||||
if (profprocs != 0) {
|
||||
profclock(USERMODE(tf->sr), tf->pc);
|
||||
}
|
||||
count_scale_factor[cpu] = 0;
|
||||
}
|
||||
/* If needed , handle count compare tick skew here */
|
||||
}
|
||||
|
||||
critical_exit();
|
||||
return (FILTER_HANDLED);
|
||||
}
|
||||
|
||||
int
|
||||
pic_hardclockhandler(struct trapframe *tf)
|
||||
{
|
||||
int cpu = PCPU_GET(cpuid);
|
||||
|
||||
critical_enter();
|
||||
|
||||
if (cpu == 0) {
|
||||
scale_factor++;
|
||||
hardclock(USERMODE(tf->sr), tf->pc);
|
||||
if (scale_factor == STAT_PROF_CLOCK_SCALE_FACTOR) {
|
||||
statclock(USERMODE(tf->sr));
|
||||
if (profprocs != 0) {
|
||||
profclock(USERMODE(tf->sr), tf->pc);
|
||||
}
|
||||
scale_factor = 0;
|
||||
}
|
||||
#ifdef XLR_PERFMON
|
||||
if (xlr_perfmon_started)
|
||||
xlr_perfmon_clockhandler();
|
||||
#endif
|
||||
|
||||
} else {
|
||||
/* If needed , handle count compare tick skew here */
|
||||
}
|
||||
critical_exit();
|
||||
return (FILTER_HANDLED);
|
||||
}
|
||||
|
||||
int
|
||||
pic_timecounthandler(struct trapframe *tf)
|
||||
{
|
||||
return (FILTER_HANDLED);
|
||||
}
|
||||
|
||||
void
|
||||
rmi_early_counter_init()
|
||||
{
|
||||
int cpu = PCPU_GET(cpuid);
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
|
||||
/*
|
||||
* We do this to get the PIC time counter running right after system
|
||||
* start. Otherwise the DELAY() function will not be able to work
|
||||
* since it won't have a TC to read.
|
||||
*/
|
||||
xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff));
|
||||
xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0xffffffff & 0xffffffff));
|
||||
xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu));
|
||||
xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_6_IRQ));
|
||||
pic_update_control(1 << (8 + 6));
|
||||
}
|
||||
|
||||
void tick_init(void);
|
||||
|
||||
void
|
||||
platform_initclocks(void)
|
||||
{
|
||||
int cpu = PCPU_GET(cpuid);
|
||||
void *cookie;
|
||||
|
||||
/*
|
||||
* Note: Passing #3 as NULL ensures that clockhandler gets called
|
||||
* with trapframe
|
||||
*/
|
||||
/* profiling/process accounting timer interrupt for non-zero cpus */
|
||||
cpu_establish_hardintr("compare",
|
||||
(driver_filter_t *) count_compare_clockhandler,
|
||||
NULL,
|
||||
NULL,
|
||||
IRQ_TIMER,
|
||||
INTR_TYPE_CLK | INTR_FAST, &cookie);
|
||||
|
||||
/* timekeeping timer interrupt for cpu 0 */
|
||||
cpu_establish_hardintr("hardclk",
|
||||
(driver_filter_t *) pic_hardclockhandler,
|
||||
NULL,
|
||||
NULL,
|
||||
PIC_TIMER_7_IRQ,
|
||||
INTR_TYPE_CLK | INTR_FAST,
|
||||
&cookie);
|
||||
|
||||
/* this is used by timecounter */
|
||||
cpu_establish_hardintr("timecount",
|
||||
(driver_filter_t *) pic_timecounthandler, NULL,
|
||||
NULL, PIC_TIMER_6_IRQ, INTR_TYPE_CLK | INTR_FAST,
|
||||
&cookie);
|
||||
|
||||
if (cpu == 0) {
|
||||
__uint64_t maxval = XLR_PIC_HZ / hz;
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
|
||||
stathz = hz / STAT_PROF_CLOCK_SCALE_FACTOR;
|
||||
profhz = stathz;
|
||||
|
||||
/* Setup PIC Interrupt */
|
||||
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff)); /* 0x100 + 7 */
|
||||
xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff); /* 0x110 + 7 */
|
||||
/* 0x40 + 8 */
|
||||
/* reg 40 is lower bits 31-0 and holds CPU mask */
|
||||
xlr_write_reg(mmio, PIC_IRT_0_TIMER_7, (1 << cpu));
|
||||
/* 0x80 + 8 */
|
||||
/* Reg 80 is upper bits 63-32 and holds */
|
||||
/* Valid Edge Local IRQ */
|
||||
xlr_write_reg(mmio, PIC_IRT_1_TIMER_7, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_7_IRQ));
|
||||
pic_update_control(1 << (8 + 7));
|
||||
|
||||
xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff));
|
||||
xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0x0 & 0xffffffff));
|
||||
xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu));
|
||||
xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_6_IRQ));
|
||||
pic_update_control(1 << (8 + 6));
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
} else {
|
||||
/* Setup count-compare interrupt for vcpu[1-31] */
|
||||
mips_wr_compare((xlr_boot1_info.cpu_frequency) / hz);
|
||||
}
|
||||
tick_init();
|
||||
}
|
||||
|
||||
unsigned
|
||||
__attribute__((no_instrument_function))
|
||||
platform_get_timecount(struct timecounter *tc __unused)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
|
||||
return 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0);
|
||||
}
|
||||
|
||||
void
|
||||
DELAY(int n)
|
||||
{
|
||||
uint32_t cur, last, delta, usecs;
|
||||
|
||||
/*
|
||||
* This works by polling the timer and counting the number of
|
||||
* microseconds that go by.
|
||||
*/
|
||||
last = platform_get_timecount(NULL);
|
||||
delta = usecs = 0;
|
||||
|
||||
while (n > usecs) {
|
||||
cur = platform_get_timecount(NULL);
|
||||
|
||||
/* Check to see if the timer has wrapped around. */
|
||||
if (cur < last)
|
||||
delta += (cur + (cycles_per_hz - last));
|
||||
else
|
||||
delta += (cur - last);
|
||||
|
||||
last = cur;
|
||||
|
||||
if (delta >= cycles_per_usec) {
|
||||
usecs += delta / cycles_per_usec;
|
||||
delta %= cycles_per_usec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
uint64_t
|
||||
read_pic_counter(void)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
uint32_t lower, upper;
|
||||
uint64_t tc;
|
||||
|
||||
/*
|
||||
* Pull the value of the 64 bit counter which is stored in PIC
|
||||
* register 120+N and 130+N
|
||||
*/
|
||||
upper = 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_1);
|
||||
lower = 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0);
|
||||
tc = (((uint64_t) upper << 32) | (uint64_t) lower);
|
||||
return (tc);
|
||||
}
|
||||
|
||||
extern struct timecounter counter_timecounter;
|
||||
|
||||
void
|
||||
mips_timer_init_params(uint64_t platform_counter_freq, int double_count)
|
||||
{
|
||||
|
||||
/*
|
||||
* XXX: Do not use printf here: uart code 8250 may use DELAY so this
|
||||
* function should be called before cninit.
|
||||
*/
|
||||
counter_freq = platform_counter_freq;
|
||||
/*
|
||||
* XXX: Some MIPS32 cores update the Count register only every two
|
||||
* pipeline cycles.
|
||||
*/
|
||||
if (double_count != 0)
|
||||
counter_freq /= 2;
|
||||
|
||||
cycles_per_tick = counter_freq / 1000;
|
||||
cycles_per_hz = counter_freq / hz;
|
||||
cycles_per_usec = counter_freq / (1 * 1000 * 1000);
|
||||
cycles_per_sec = counter_freq;
|
||||
|
||||
counter_timecounter.tc_frequency = counter_freq;
|
||||
printf("hz=%d cyl_per_hz:%jd cyl_per_usec:%jd freq:%jd cyl_per_hz:%jd cyl_per_sec:%jd\n",
|
||||
hz,
|
||||
cycles_per_tick,
|
||||
cycles_per_usec,
|
||||
counter_freq,
|
||||
cycles_per_hz,
|
||||
cycles_per_sec
|
||||
);
|
||||
set_cputicker(read_pic_counter, counter_freq, 1);
|
||||
}
|
41
sys/mips/rmi/clock.h
Normal file
41
sys/mips/rmi/clock.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
#ifndef _RMI_CLOCK_H_
|
||||
#define _RMI_CLOCK_H_
|
||||
|
||||
#define XLR_PIC_HZ 66000000U
|
||||
#define XLR_CPU_HZ (xlr_boot1_info.cpu_frequency)
|
||||
|
||||
int count_compare_clockhandler(struct trapframe *);
|
||||
int pic_hardclockhandler(struct trapframe *);
|
||||
int pic_timecounthandler(struct trapframe *);
|
||||
void rmi_early_counter_init(void);
|
||||
|
||||
#endif /* _RMI_CLOCK_H_ */
|
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
|
309
sys/mips/rmi/ehcireg.h
Normal file
309
sys/mips/rmi/ehcireg.h
Normal file
@ -0,0 +1,309 @@
|
||||
/* $NetBSD: ehcireg.h,v 1.18 2004/10/22 10:38:17 augustss Exp $ */
|
||||
/* $FreeBSD: src/sys/dev/usb/ehcireg.h,v 1.7.2.2.2.1 2008/10/02 02:57:24 kensmith Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Lennart Augustsson (lennart@augustsson.net).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The EHCI 0.96 spec can be found at
|
||||
* http://developer.intel.com/technology/usb/download/ehci-r096.pdf
|
||||
* and the USB 2.0 spec at
|
||||
* http://www.usb.org/developers/data/usb_20.zip
|
||||
*/
|
||||
|
||||
#ifndef _DEV_PCI_EHCIREG_H_
|
||||
#define _DEV_PCI_EHCIREG_H_
|
||||
|
||||
/*** PCI config registers ***/
|
||||
|
||||
#define PCI_CBMEM 0x10 /* configuration base MEM */
|
||||
|
||||
#define PCI_INTERFACE_EHCI 0x20
|
||||
|
||||
#define PCI_USBREV 0x60 /* RO USB protocol revision */
|
||||
#define PCI_USBREV_MASK 0xff
|
||||
#define PCI_USBREV_PRE_1_0 0x00
|
||||
#define PCI_USBREV_1_0 0x10
|
||||
#define PCI_USBREV_1_1 0x11
|
||||
#define PCI_USBREV_2_0 0x20
|
||||
|
||||
#define PCI_EHCI_FLADJ 0x61 /* RW Frame len adj, SOF=59488+6*fladj */
|
||||
|
||||
#define PCI_EHCI_PORTWAKECAP 0x62 /* RW Port wake caps (opt) */
|
||||
|
||||
/* EHCI Extended Capabilities */
|
||||
#define EHCI_EC_LEGSUP 0x01
|
||||
|
||||
#define EHCI_EECP_NEXT(x) (((x) >> 8) & 0xff)
|
||||
#define EHCI_EECP_ID(x) ((x) & 0xff)
|
||||
|
||||
/* Legacy support extended capability */
|
||||
#define EHCI_LEGSUP_OS_SEM 0x03 /* OS owned semaphore */
|
||||
#define EHCI_LEGSUP_BIOS_SEM 0x02 /* BIOS owned semaphore */
|
||||
#define EHCI_LEGSUP_USBLEGCTLSTS 0x04
|
||||
|
||||
/*** EHCI capability registers ***/
|
||||
|
||||
#define EHCI_CAPLENGTH 0x00 /* RO Capability register length field */
|
||||
/* reserved 0x01 */
|
||||
#define EHCI_HCIVERSION 0x02 /* RO Interface version number */
|
||||
|
||||
#define EHCI_HCSPARAMS 0x04 /* RO Structural parameters */
|
||||
#define EHCI_HCS_DEBUGPORT(x) (((x) >> 20) & 0xf)
|
||||
#define EHCI_HCS_P_INDICATOR(x) ((x) & 0x10000)
|
||||
#define EHCI_HCS_N_CC(x) (((x) >> 12) & 0xf) /* # of companion ctlrs */
|
||||
#define EHCI_HCS_N_PCC(x) (((x) >> 8) & 0xf) /* # of ports per comp. */
|
||||
#define EHCI_HCS_PPC(x) ((x) & 0x10) /* port power control */
|
||||
#define EHCI_HCS_N_PORTS(x) ((x) & 0xf) /* # of ports */
|
||||
|
||||
#define EHCI_HCCPARAMS 0x08 /* RO Capability parameters */
|
||||
#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */
|
||||
#define EHCI_HCC_IST(x) (((x) >> 4) & 0xf) /* isoc sched threshold */
|
||||
#define EHCI_HCC_ASPC(x) ((x) & 0x4) /* async sched park cap */
|
||||
#define EHCI_HCC_PFLF(x) ((x) & 0x2) /* prog frame list flag */
|
||||
#define EHCI_HCC_64BIT(x) ((x) & 0x1) /* 64 bit address cap */
|
||||
|
||||
#define EHCI_HCSP_PORTROUTE 0x0c /* RO Companion port route description */
|
||||
|
||||
/* EHCI operational registers. Offset given by EHCI_CAPLENGTH register */
|
||||
#define EHCI_USBCMD 0x00 /* RO, RW, WO Command register */
|
||||
#define EHCI_CMD_ITC_M 0x00ff0000 /* RW interrupt threshold ctrl */
|
||||
#define EHCI_CMD_ITC_1 0x00010000
|
||||
#define EHCI_CMD_ITC_2 0x00020000
|
||||
#define EHCI_CMD_ITC_4 0x00040000
|
||||
#define EHCI_CMD_ITC_8 0x00080000
|
||||
#define EHCI_CMD_ITC_16 0x00100000
|
||||
#define EHCI_CMD_ITC_32 0x00200000
|
||||
#define EHCI_CMD_ITC_64 0x00400000
|
||||
#define EHCI_CMD_ASPME 0x00000800 /* RW/RO async park enable */
|
||||
#define EHCI_CMD_ASPMC 0x00000300 /* RW/RO async park count */
|
||||
#define EHCI_CMD_LHCR 0x00000080 /* RW light host ctrl reset */
|
||||
#define EHCI_CMD_IAAD 0x00000040 /* RW intr on async adv door
|
||||
* bell */
|
||||
#define EHCI_CMD_ASE 0x00000020 /* RW async sched enable */
|
||||
#define EHCI_CMD_PSE 0x00000010 /* RW periodic sched enable */
|
||||
#define EHCI_CMD_FLS_M 0x0000000c /* RW/RO frame list size */
|
||||
#define EHCI_CMD_FLS(x) (((x) >> 2) & 3) /* RW/RO frame list size */
|
||||
#define EHCI_CMD_HCRESET 0x00000002 /* RW reset */
|
||||
#define EHCI_CMD_RS 0x00000001 /* RW run/stop */
|
||||
|
||||
#define EHCI_USBSTS 0x04 /* RO, RW, RWC Status register */
|
||||
#define EHCI_STS_ASS 0x00008000 /* RO async sched status */
|
||||
#define EHCI_STS_PSS 0x00004000 /* RO periodic sched status */
|
||||
#define EHCI_STS_REC 0x00002000 /* RO reclamation */
|
||||
#define EHCI_STS_HCH 0x00001000 /* RO host controller halted */
|
||||
#define EHCI_STS_IAA 0x00000020 /* RWC interrupt on async adv */
|
||||
#define EHCI_STS_HSE 0x00000010 /* RWC host system error */
|
||||
#define EHCI_STS_FLR 0x00000008 /* RWC frame list rollover */
|
||||
#define EHCI_STS_PCD 0x00000004 /* RWC port change detect */
|
||||
#define EHCI_STS_ERRINT 0x00000002 /* RWC error interrupt */
|
||||
#define EHCI_STS_INT 0x00000001 /* RWC interrupt */
|
||||
#define EHCI_STS_INTRS(x) ((x) & 0x3f)
|
||||
|
||||
#define EHCI_NORMAL_INTRS (EHCI_STS_IAA | EHCI_STS_HSE | EHCI_STS_PCD | EHCI_STS_ERRINT | EHCI_STS_INT)
|
||||
|
||||
#define EHCI_USBINTR 0x08 /* RW Interrupt register */
|
||||
#define EHCI_INTR_IAAE 0x00000020 /* interrupt on async advance
|
||||
* ena */
|
||||
#define EHCI_INTR_HSEE 0x00000010 /* host system error ena */
|
||||
#define EHCI_INTR_FLRE 0x00000008 /* frame list rollover ena */
|
||||
#define EHCI_INTR_PCIE 0x00000004 /* port change ena */
|
||||
#define EHCI_INTR_UEIE 0x00000002 /* USB error intr ena */
|
||||
#define EHCI_INTR_UIE 0x00000001 /* USB intr ena */
|
||||
|
||||
#define EHCI_FRINDEX 0x0c /* RW Frame Index register */
|
||||
|
||||
#define EHCI_CTRLDSSEGMENT 0x10 /* RW Control Data Structure Segment */
|
||||
|
||||
#define EHCI_PERIODICLISTBASE 0x14 /* RW Periodic List Base */
|
||||
#define EHCI_ASYNCLISTADDR 0x18 /* RW Async List Base */
|
||||
|
||||
#define EHCI_CONFIGFLAG 0x40 /* RW Configure Flag register */
|
||||
#define EHCI_CONF_CF 0x00000001 /* RW configure flag */
|
||||
|
||||
#define EHCI_PORTSC(n) (0x40+4*(n)) /* RO, RW, RWC Port Status reg */
|
||||
#define EHCI_PS_WKOC_E 0x00400000 /* RW wake on over current ena */
|
||||
#define EHCI_PS_WKDSCNNT_E 0x00200000 /* RW wake on disconnect ena */
|
||||
#define EHCI_PS_WKCNNT_E 0x00100000 /* RW wake on connect ena */
|
||||
#define EHCI_PS_PTC 0x000f0000 /* RW port test control */
|
||||
#define EHCI_PS_PIC 0x0000c000 /* RW port indicator control */
|
||||
#define EHCI_PS_PO 0x00002000 /* RW port owner */
|
||||
#define EHCI_PS_PP 0x00001000 /* RW,RO port power */
|
||||
#define EHCI_PS_LS 0x00000c00 /* RO line status */
|
||||
#define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == 0x00000400)
|
||||
#define EHCI_PS_PR 0x00000100 /* RW port reset */
|
||||
#define EHCI_PS_SUSP 0x00000080 /* RW suspend */
|
||||
#define EHCI_PS_FPR 0x00000040 /* RW force port resume */
|
||||
#define EHCI_PS_OCC 0x00000020 /* RWC over current change */
|
||||
#define EHCI_PS_OCA 0x00000010 /* RO over current active */
|
||||
#define EHCI_PS_PEC 0x00000008 /* RWC port enable change */
|
||||
#define EHCI_PS_PE 0x00000004 /* RW port enable */
|
||||
#define EHCI_PS_CSC 0x00000002 /* RWC connect status change */
|
||||
#define EHCI_PS_CS 0x00000001 /* RO connect status */
|
||||
#define EHCI_PS_CLEAR (EHCI_PS_OCC|EHCI_PS_PEC|EHCI_PS_CSC)
|
||||
|
||||
#define EHCI_PORT_RESET_COMPLETE 2 /* ms */
|
||||
|
||||
#define EHCI_FLALIGN_ALIGN 0x1000
|
||||
|
||||
/* No data structure may cross a page boundary. */
|
||||
#define EHCI_PAGE_SIZE 0x1000
|
||||
#define EHCI_PAGE(x) ((x) &~ 0xfff)
|
||||
#define EHCI_PAGE_OFFSET(x) ((x) & 0xfff)
|
||||
#if defined(__FreeBSD__)
|
||||
#define EHCI_PAGE_MASK(x) ((x) & 0xfff)
|
||||
#endif
|
||||
|
||||
typedef u_int32_t ehci_link_t;
|
||||
|
||||
#define EHCI_LINK_TERMINATE 0x00000001
|
||||
#define EHCI_LINK_TYPE(x) ((x) & 0x00000006)
|
||||
#define EHCI_LINK_ITD 0x0
|
||||
#define EHCI_LINK_QH 0x2
|
||||
#define EHCI_LINK_SITD 0x4
|
||||
#define EHCI_LINK_FSTN 0x6
|
||||
#define EHCI_LINK_ADDR(x) ((x) &~ 0x1f)
|
||||
|
||||
typedef u_int32_t ehci_physaddr_t;
|
||||
|
||||
/* Isochronous Transfer Descriptor */
|
||||
typedef struct {
|
||||
ehci_link_t itd_next;
|
||||
/* XXX many more */
|
||||
} ehci_itd_t;
|
||||
|
||||
#define EHCI_ITD_ALIGN 32
|
||||
|
||||
/* Split Transaction Isochronous Transfer Descriptor */
|
||||
typedef struct {
|
||||
ehci_link_t sitd_next;
|
||||
/* XXX many more */
|
||||
} ehci_sitd_t;
|
||||
|
||||
#define EHCI_SITD_ALIGN 32
|
||||
|
||||
/* Queue Element Transfer Descriptor */
|
||||
#define EHCI_QTD_NBUFFERS 5
|
||||
typedef struct {
|
||||
ehci_link_t qtd_next;
|
||||
ehci_link_t qtd_altnext;
|
||||
u_int32_t qtd_status;
|
||||
#define EHCI_QTD_GET_STATUS(x) (((x) >> 0) & 0xff)
|
||||
#define EHCI_QTD_SET_STATUS(x) ((x) << 0)
|
||||
#define EHCI_QTD_ACTIVE 0x80
|
||||
#define EHCI_QTD_HALTED 0x40
|
||||
#define EHCI_QTD_BUFERR 0x20
|
||||
#define EHCI_QTD_BABBLE 0x10
|
||||
#define EHCI_QTD_XACTERR 0x08
|
||||
#define EHCI_QTD_MISSEDMICRO 0x04
|
||||
#define EHCI_QTD_SPLITXSTATE 0x02
|
||||
#define EHCI_QTD_PINGSTATE 0x01
|
||||
#define EHCI_QTD_STATERRS 0x7c
|
||||
#define EHCI_QTD_GET_PID(x) (((x) >> 8) & 0x3)
|
||||
#define EHCI_QTD_SET_PID(x) ((x) << 8)
|
||||
#define EHCI_QTD_PID_OUT 0x0
|
||||
#define EHCI_QTD_PID_IN 0x1
|
||||
#define EHCI_QTD_PID_SETUP 0x2
|
||||
#define EHCI_QTD_GET_CERR(x) (((x) >> 10) & 0x3)
|
||||
#define EHCI_QTD_SET_CERR(x) ((x) << 10)
|
||||
#define EHCI_QTD_GET_C_PAGE(x) (((x) >> 12) & 0x7)
|
||||
#define EHCI_QTD_SET_C_PAGE(x) ((x) << 12)
|
||||
#define EHCI_QTD_GET_IOC(x) (((x) >> 15) & 0x1)
|
||||
#define EHCI_QTD_IOC 0x00008000
|
||||
#define EHCI_QTD_GET_BYTES(x) (((x) >> 16) & 0x7fff)
|
||||
#define EHCI_QTD_SET_BYTES(x) ((x) << 16)
|
||||
#define EHCI_QTD_GET_TOGGLE(x) (((x) >> 31) & 0x1)
|
||||
#define EHCI_QTD_SET_TOGGLE(x) ((x) << 31)
|
||||
#define EHCI_QTD_TOGGLE_MASK 0x80000000
|
||||
ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS];
|
||||
ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
|
||||
} ehci_qtd_t;
|
||||
|
||||
#define EHCI_QTD_ALIGN 32
|
||||
|
||||
/* Queue Head */
|
||||
typedef struct {
|
||||
ehci_link_t qh_link;
|
||||
u_int32_t qh_endp;
|
||||
#define EHCI_QH_GET_ADDR(x) (((x) >> 0) & 0x7f) /* endpoint addr */
|
||||
#define EHCI_QH_SET_ADDR(x) (x)
|
||||
#define EHCI_QH_ADDRMASK 0x0000007f
|
||||
#define EHCI_QH_GET_INACT(x) (((x) >> 7) & 0x01) /* inactivate on next */
|
||||
#define EHCI_QH_INACT 0x00000080
|
||||
#define EHCI_QH_GET_ENDPT(x) (((x) >> 8) & 0x0f) /* endpoint no */
|
||||
#define EHCI_QH_SET_ENDPT(x) ((x) << 8)
|
||||
#define EHCI_QH_GET_EPS(x) (((x) >> 12) & 0x03) /* endpoint speed */
|
||||
#define EHCI_QH_SET_EPS(x) ((x) << 12)
|
||||
#define EHCI_QH_SPEED_FULL 0x0
|
||||
#define EHCI_QH_SPEED_LOW 0x1
|
||||
#define EHCI_QH_SPEED_HIGH 0x2
|
||||
#define EHCI_QH_GET_DTC(x) (((x) >> 14) & 0x01) /* data toggle control */
|
||||
#define EHCI_QH_DTC 0x00004000
|
||||
#define EHCI_QH_GET_HRECL(x) (((x) >> 15) & 0x01) /* head of reclamation */
|
||||
#define EHCI_QH_HRECL 0x00008000
|
||||
#define EHCI_QH_GET_MPL(x) (((x) >> 16) & 0x7ff) /* max packet len */
|
||||
#define EHCI_QH_SET_MPL(x) ((x) << 16)
|
||||
#define EHCI_QH_MPLMASK 0x07ff0000
|
||||
#define EHCI_QH_GET_CTL(x) (((x) >> 27) & 0x01) /* control endpoint */
|
||||
#define EHCI_QH_CTL 0x08000000
|
||||
#define EHCI_QH_GET_NRL(x) (((x) >> 28) & 0x0f) /* NAK reload */
|
||||
#define EHCI_QH_SET_NRL(x) ((x) << 28)
|
||||
u_int32_t qh_endphub;
|
||||
#define EHCI_QH_GET_SMASK(x) (((x) >> 0) & 0xff) /* intr sched mask */
|
||||
#define EHCI_QH_SET_SMASK(x) ((x) << 0)
|
||||
#define EHCI_QH_GET_CMASK(x) (((x) >> 8) & 0xff) /* split completion mask */
|
||||
#define EHCI_QH_SET_CMASK(x) ((x) << 8)
|
||||
#define EHCI_QH_GET_HUBA(x) (((x) >> 16) & 0x7f) /* hub address */
|
||||
#define EHCI_QH_SET_HUBA(x) ((x) << 16)
|
||||
#define EHCI_QH_GET_PORT(x) (((x) >> 23) & 0x7f) /* hub port */
|
||||
#define EHCI_QH_SET_PORT(x) ((x) << 23)
|
||||
#define EHCI_QH_GET_MULT(x) (((x) >> 30) & 0x03) /* pipe multiplier */
|
||||
#define EHCI_QH_SET_MULT(x) ((x) << 30)
|
||||
ehci_link_t qh_curqtd;
|
||||
ehci_qtd_t qh_qtd;
|
||||
} ehci_qh_t;
|
||||
|
||||
#define EHCI_QH_ALIGN 32
|
||||
|
||||
/* Periodic Frame Span Traversal Node */
|
||||
typedef struct {
|
||||
ehci_link_t fstn_link;
|
||||
ehci_link_t fstn_back;
|
||||
} ehci_fstn_t;
|
||||
|
||||
#define EHCI_FSTN_ALIGN 32
|
||||
|
||||
#endif /* _DEV_PCI_EHCIREG_H_ */
|
195
sys/mips/rmi/ehcivar.h
Normal file
195
sys/mips/rmi/ehcivar.h
Normal file
@ -0,0 +1,195 @@
|
||||
/* $NetBSD: ehcivar.h,v 1.19 2005/04/29 15:04:29 augustss Exp $ */
|
||||
/* $FreeBSD: src/sys/dev/usb/ehcivar.h,v 1.9.2.1.8.1 2008/10/02 02:57:24 kensmith Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Lennart Augustsson (lennart@augustsson.net).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
typedef struct ehci_soft_qtd {
|
||||
ehci_qtd_t qtd;
|
||||
struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */
|
||||
ehci_physaddr_t physaddr;
|
||||
usbd_xfer_handle xfer;
|
||||
LIST_ENTRY(ehci_soft_qtd) hnext;
|
||||
u_int16_t len;
|
||||
} ehci_soft_qtd_t;
|
||||
|
||||
#define EHCI_SQTD_SIZE ((sizeof (struct ehci_soft_qtd) + EHCI_QTD_ALIGN - 1) / EHCI_QTD_ALIGN * EHCI_QTD_ALIGN)
|
||||
#define EHCI_SQTD_CHUNK (EHCI_PAGE_SIZE / EHCI_SQTD_SIZE)
|
||||
|
||||
typedef struct ehci_soft_qh {
|
||||
ehci_qh_t qh;
|
||||
struct ehci_soft_qh *next;
|
||||
struct ehci_soft_qh *prev;
|
||||
struct ehci_soft_qtd *sqtd;
|
||||
ehci_physaddr_t physaddr;
|
||||
int islot; /* Interrupt list slot. */
|
||||
} ehci_soft_qh_t;
|
||||
|
||||
#define EHCI_SQH_SIZE ((sizeof (struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN)
|
||||
#define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE)
|
||||
|
||||
struct ehci_xfer {
|
||||
struct usbd_xfer xfer;
|
||||
struct usb_task abort_task;
|
||||
LIST_ENTRY(ehci_xfer) inext; /* list of active xfers */
|
||||
ehci_soft_qtd_t *sqtdstart;
|
||||
ehci_soft_qtd_t *sqtdend;
|
||||
u_int32_t ehci_xfer_flags;
|
||||
#ifdef DIAGNOSTIC
|
||||
int isdone;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define EHCI_XFER_ABORTING 0x0001 /* xfer is aborting. */
|
||||
#define EHCI_XFER_ABORTWAIT 0x0002 /* abort completion is being awaited. */
|
||||
|
||||
#define EXFER(xfer) ((struct ehci_xfer *)(xfer))
|
||||
|
||||
/*
|
||||
* Information about an entry in the interrupt list.
|
||||
*/
|
||||
struct ehci_soft_islot {
|
||||
ehci_soft_qh_t *sqh; /* Queue Head. */
|
||||
};
|
||||
|
||||
#define EHCI_FRAMELIST_MAXCOUNT 1024
|
||||
#define EHCI_IPOLLRATES 8 /* Poll rates (1ms, 2, 4, 8 ... 128) */
|
||||
#define EHCI_INTRQHS ((1 << EHCI_IPOLLRATES) - 1)
|
||||
#define EHCI_MAX_POLLRATE (1 << (EHCI_IPOLLRATES - 1))
|
||||
#define EHCI_IQHIDX(lev, pos) \
|
||||
((((pos) & ((1 << (lev)) - 1)) | (1 << (lev))) - 1)
|
||||
#define EHCI_ILEV_IVAL(lev) (1 << (lev))
|
||||
|
||||
#define EHCI_HASH_SIZE 128
|
||||
#define EHCI_COMPANION_MAX 8
|
||||
|
||||
#define EHCI_SCFLG_DONEINIT 0x0001 /* ehci_init() has been called. */
|
||||
#define EHCI_SCFLG_LOSTINTRBUG 0x0002 /* workaround for VIA / ATI chipsets */
|
||||
|
||||
typedef struct ehci_softc {
|
||||
struct usbd_bus sc_bus; /* base device */
|
||||
int sc_flags;
|
||||
bus_space_tag_t iot;
|
||||
bus_space_handle_t ioh;
|
||||
bus_size_t sc_size;
|
||||
#if defined(__FreeBSD__)
|
||||
void *ih;
|
||||
|
||||
struct resource *io_res;
|
||||
struct resource *irq_res;
|
||||
#endif
|
||||
u_int sc_offs; /* offset to operational regs */
|
||||
|
||||
char sc_vendor[32]; /* vendor string for root hub */
|
||||
int sc_id_vendor; /* vendor ID for root hub */
|
||||
|
||||
u_int32_t sc_cmd; /* shadow of cmd reg during suspend */
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
void *sc_powerhook; /* cookie from power hook */
|
||||
void *sc_shutdownhook; /* cookie from shutdown hook */
|
||||
#endif
|
||||
|
||||
u_int sc_ncomp;
|
||||
u_int sc_npcomp;
|
||||
struct usbd_bus *sc_comps[EHCI_COMPANION_MAX];
|
||||
|
||||
usb_dma_t sc_fldma;
|
||||
ehci_link_t *sc_flist;
|
||||
u_int sc_flsize;
|
||||
#ifndef __FreeBSD__
|
||||
u_int sc_rand; /* XXX need proper intr scheduling */
|
||||
#endif
|
||||
|
||||
struct ehci_soft_islot sc_islots[EHCI_INTRQHS];
|
||||
|
||||
LIST_HEAD(, ehci_xfer) sc_intrhead;
|
||||
|
||||
ehci_soft_qh_t *sc_freeqhs;
|
||||
ehci_soft_qtd_t *sc_freeqtds;
|
||||
|
||||
int sc_noport;
|
||||
u_int8_t sc_addr; /* device address */
|
||||
u_int8_t sc_conf; /* device configuration */
|
||||
usbd_xfer_handle sc_intrxfer;
|
||||
char sc_isreset;
|
||||
#ifdef USB_USE_SOFTINTR
|
||||
char sc_softwake;
|
||||
#endif /* USB_USE_SOFTINTR */
|
||||
|
||||
u_int32_t sc_eintrs;
|
||||
ehci_soft_qh_t *sc_async_head;
|
||||
|
||||
SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
|
||||
|
||||
struct lock sc_doorbell_lock;
|
||||
|
||||
usb_callout_t sc_tmo_pcd;
|
||||
usb_callout_t sc_tmo_intrlist;
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
device_ptr_t sc_child; /* /dev/usb# device */
|
||||
#endif
|
||||
char sc_dying;
|
||||
#if defined(__NetBSD__)
|
||||
struct usb_dma_reserve sc_dma_reserve;
|
||||
#endif
|
||||
} ehci_softc_t;
|
||||
|
||||
#define EREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a))
|
||||
#define EREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a))
|
||||
#define EREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a))
|
||||
#define EWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x))
|
||||
#define EWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x))
|
||||
#define EWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x))
|
||||
#define EOREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
|
||||
#define EOREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
|
||||
#define EOREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
|
||||
#define EOWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
|
||||
#define EOWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
|
||||
#define EOWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
|
||||
|
||||
usbd_status ehci_init(ehci_softc_t *);
|
||||
int ehci_intr(void *);
|
||||
int ehci_detach(ehci_softc_t *, int);
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
int ehci_activate(device_ptr_t, enum devact);
|
||||
|
||||
#endif
|
||||
void ehci_power(int state, void *priv);
|
||||
void ehci_shutdown(void *v);
|
||||
|
||||
#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
|
26
sys/mips/rmi/files.xlr
Normal file
26
sys/mips/rmi/files.xlr
Normal file
@ -0,0 +1,26 @@
|
||||
# $FreeBSD$
|
||||
#mips/rmi/xlr_boot1_console.c standard
|
||||
mips/rmi/xlr_machdep.c standard
|
||||
mips/rmi/clock.c standard
|
||||
mips/rmi/tick.c standard
|
||||
mips/rmi/iodi.c standard
|
||||
mips/rmi/msgring.c standard
|
||||
mips/rmi/msgring_xls.c standard
|
||||
mips/rmi/board.c standard
|
||||
mips/rmi/on_chip.c standard
|
||||
mips/rmi/intr_machdep.c standard
|
||||
mips/rmi/xlr_i2c.c optional iic
|
||||
mips/rmi/uart_bus_xlr_iodi.c optional uart
|
||||
mips/rmi/uart_cpu_mips_xlr.c optional uart
|
||||
mips/rmi/perfmon_kern.c optional xlr_perfmon
|
||||
mips/rmi/perfmon_percpu.c optional xlr_perfmon
|
||||
#mips/rmi/pcibus.c optional pci
|
||||
#mips/rmi/xlr_pci.c optional pci
|
||||
#mips/rmi/xls_ehci.c optional usb ehci
|
||||
dev/rmi/xlr/rge.c optional rge
|
||||
mips/rmi/bus_space_rmi.c standard
|
||||
dev/iicbus/xlr_rtc.c optional xlr_rtc
|
||||
dev/iicbus/xlr_temperature.c optional xlr_temperature
|
||||
dev/iicbus/xlr_eeprom.c optional xlr_eeprom
|
||||
dev/rmi/sec/rmisec.c optional rmisec
|
||||
dev/rmi/sec/rmilib.c optional rmisec
|
42
sys/mips/rmi/interrupt.h
Normal file
42
sys/mips/rmi/interrupt.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
#ifndef _RMI_INTERRUPT_H_
|
||||
#define _RMI_INTERRUPT_H_
|
||||
|
||||
/* Defines for the IRQ numbers */
|
||||
|
||||
#define IRQ_DUMMY_UART 2
|
||||
#define IRQ_IPI_SMP_FUNCTION 3
|
||||
#define IRQ_IPI_SMP_RESCHEDULE 4
|
||||
#define IRQ_REMOTE_DEBUG 5
|
||||
#define IRQ_MSGRING 6
|
||||
#define IRQ_TIMER 7
|
||||
|
||||
#endif /* _RMI_INTERRUPT_H_ */
|
217
sys/mips/rmi/intr_machdep.c
Normal file
217
sys/mips/rmi/intr_machdep.c
Normal file
@ -0,0 +1,217 @@
|
||||
/*-
|
||||
* Copyright (c) 2006-2009 RMI Corporation
|
||||
* Copyright (c) 2002-2004 Juli Mallett <jmallett@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification, immediately at the beginning of the file.
|
||||
* 2. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/interrupt.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/cpuinfo.h>
|
||||
#include <machine/cpuregs.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/trap.h>
|
||||
#include <machine/hwfunc.h>
|
||||
#include <mips/rmi/xlrconfig.h>
|
||||
#include <mips/rmi/interrupt.h>
|
||||
#include <mips/rmi/clock.h>
|
||||
#include <mips/rmi/pic.h>
|
||||
|
||||
/*#include <machine/intrcnt.h>*/
|
||||
static mips_intrcnt_t mips_intr_counters[XLR_MAX_INTR];
|
||||
struct mips_intrhand mips_intr_handlers[XLR_MAX_INTR];
|
||||
static int intrcnt_index;
|
||||
|
||||
static void
|
||||
mips_mask_hard_irq(void *source)
|
||||
{
|
||||
uintptr_t irq = (uintptr_t) source;
|
||||
|
||||
write_c0_eimr64(read_c0_eimr64() & ~(1ULL << irq));
|
||||
}
|
||||
|
||||
static void
|
||||
mips_unmask_hard_irq(void *source)
|
||||
{
|
||||
uintptr_t irq = (uintptr_t) source;
|
||||
|
||||
write_c0_eimr64(read_c0_eimr64() | (1ULL << irq));
|
||||
}
|
||||
|
||||
void
|
||||
cpu_establish_hardintr(const char *name, driver_filter_t * filt,
|
||||
void (*handler) (void *), void *arg, int irq, int flags, void **cookiep)
|
||||
{
|
||||
struct mips_intrhand *mih; /* descriptor for the IRQ */
|
||||
struct intr_event *ie; /* descriptor for the IRQ */
|
||||
int errcode;
|
||||
|
||||
if (irq < 0 || irq > XLR_MAX_INTR)
|
||||
panic("%s called for unknown hard intr %d", __func__, irq);
|
||||
|
||||
/*
|
||||
* FIXME locking - not needed now, because we do this only on
|
||||
* startup from CPU0
|
||||
*/
|
||||
mih = &mips_intr_handlers[irq];
|
||||
/* mih->cntp = &intrcnt[irq]; */
|
||||
ie = mih->mih_event;
|
||||
if (ie == NULL) {
|
||||
errcode = intr_event_create(&ie, (void *)(uintptr_t) irq, 0,
|
||||
irq, mips_mask_hard_irq, mips_unmask_hard_irq,
|
||||
NULL, NULL, "hard intr%d:", irq);
|
||||
|
||||
if (errcode) {
|
||||
printf("Could not create event for intr %d\n", irq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
intr_event_add_handler(ie, name, filt, handler, arg,
|
||||
intr_priority(flags), flags, cookiep);
|
||||
mih->mih_event = ie;
|
||||
mips_unmask_hard_irq((void *)(uintptr_t) irq);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cpu_establish_softintr(const char *name, driver_filter_t * filt,
|
||||
void (*handler) (void *), void *arg, int irq, int flags,
|
||||
void **cookiep)
|
||||
{
|
||||
/* we don't separate them into soft/hard like other mips */
|
||||
cpu_establish_hardintr(name, filt, handler, arg, irq, flags, cookiep);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_intr(struct trapframe *tf)
|
||||
{
|
||||
struct mips_intrhand *mih;
|
||||
struct intr_event *ie;
|
||||
register_t eirr;
|
||||
int i;
|
||||
|
||||
critical_enter();
|
||||
eirr = read_c0_eirr64();
|
||||
if (eirr == 0) {
|
||||
critical_exit();
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* No need to clear the EIRR here. the handler is gonna write to
|
||||
* compare which clears eirr also
|
||||
*/
|
||||
if (eirr & (1 << IRQ_TIMER)) {
|
||||
count_compare_clockhandler(tf);
|
||||
critical_exit();
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME sched pin >? LOCK>? */
|
||||
for (i = sizeof(eirr) * 8 - 1; i >= 0; i--) {
|
||||
if ((eirr & (1ULL << i)) == 0)
|
||||
continue;
|
||||
#ifdef SMP
|
||||
/* These are reserved interrupts */
|
||||
if ((i == IPI_AST) || (i == IPI_RENDEZVOUS) || (i == IPI_STOP)
|
||||
|| (i == IPI_SMP_CALL_FUNCTION)) {
|
||||
write_c0_eirr64(1ULL << i);
|
||||
pic_ack(i);
|
||||
smp_handle_ipi(tf, i);
|
||||
pic_delayed_ack(i);
|
||||
continue;
|
||||
}
|
||||
#ifdef XLR_PERFMON
|
||||
if (i == IPI_PERFMON) {
|
||||
write_c0_eirr64(1ULL << i);
|
||||
pic_ack(i);
|
||||
xlr_perfmon_sampler(NULL);
|
||||
pic_delayed_ack(i);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
mih = &mips_intr_handlers[i];
|
||||
/* atomic_add_long(mih->cntp, 1); */
|
||||
ie = mih->mih_event;
|
||||
|
||||
write_c0_eirr64(1ULL << i);
|
||||
pic_ack(i);
|
||||
if (!ie || TAILQ_EMPTY(&ie->ie_handlers)) {
|
||||
printf("stray interrupt %d\n", i);
|
||||
continue;
|
||||
}
|
||||
if (intr_event_handle(ie, tf) != 0) {
|
||||
printf("stray interrupt %d\n", i);
|
||||
}
|
||||
pic_delayed_ack(i);
|
||||
}
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
void
|
||||
mips_intrcnt_setname(mips_intrcnt_t counter, const char *name)
|
||||
{
|
||||
int idx = counter - intrcnt;
|
||||
|
||||
KASSERT(counter != NULL, ("mips_intrcnt_setname: NULL counter"));
|
||||
|
||||
snprintf(intrnames + (MAXCOMLEN + 1) * idx,
|
||||
MAXCOMLEN + 1, "%-*s", MAXCOMLEN, name);
|
||||
}
|
||||
|
||||
mips_intrcnt_t
|
||||
mips_intrcnt_create(const char* name)
|
||||
{
|
||||
mips_intrcnt_t counter = &intrcnt[intrcnt_index++];
|
||||
|
||||
mips_intrcnt_setname(counter, name);
|
||||
return counter;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_init_interrupts()
|
||||
{
|
||||
int i;
|
||||
char name[MAXCOMLEN + 1];
|
||||
|
||||
/*
|
||||
* Initialize all available vectors so spare IRQ
|
||||
* would show up in systat output
|
||||
*/
|
||||
for (i = 0; i < XLR_MAX_INTR; i++) {
|
||||
snprintf(name, MAXCOMLEN + 1, "int%d:", i);
|
||||
mips_intr_counters[i] = mips_intrcnt_create(name);
|
||||
}
|
||||
}
|
308
sys/mips/rmi/iodi.c
Normal file
308
sys/mips/rmi/iodi.c
Normal file
@ -0,0 +1,308 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
|
||||
#define __RMAN_RESOURCE_VISIBLE
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/interrupt.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <mips/rmi/iomap.h>
|
||||
#include <mips/rmi/pic.h>
|
||||
#include <mips/rmi/shared_structs.h>
|
||||
#include <mips/rmi/board.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
|
||||
#include <machine/param.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <mips/rmi/interrupt.h>
|
||||
#include <mips/rmi/msgring.h>
|
||||
#include <mips/rmi/iomap.h>
|
||||
#include <mips/rmi/debug.h>
|
||||
#include <mips/rmi/pic.h>
|
||||
#include <mips/rmi/xlrconfig.h>
|
||||
#include <mips/rmi/shared_structs.h>
|
||||
#include <mips/rmi/board.h>
|
||||
|
||||
#include <dev/rmi/xlr/atx_cpld.h>
|
||||
#include <dev/rmi/xlr/xgmac_mdio.h>
|
||||
|
||||
extern void iodi_activateirqs(void);
|
||||
|
||||
extern bus_space_tag_t uart_bus_space_mem;
|
||||
|
||||
static struct resource *
|
||||
iodi_alloc_resource(device_t, device_t, int, int *,
|
||||
u_long, u_long, u_long, u_int);
|
||||
|
||||
static int
|
||||
iodi_activate_resource(device_t, device_t, int, int,
|
||||
struct resource *);
|
||||
static int
|
||||
iodi_setup_intr(device_t, device_t, struct resource *, int,
|
||||
driver_filter_t *, driver_intr_t *, void *, void **);
|
||||
|
||||
struct iodi_softc *iodi_softc; /* There can be only one. */
|
||||
|
||||
/*
|
||||
static void pic_usb_ack(void *arg)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
int irq = PIC_USB_IRQ ;
|
||||
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static int
|
||||
iodi_setup_intr(device_t dev, device_t child,
|
||||
struct resource *ires, int flags, driver_filter_t * filt, driver_intr_t * intr, void *arg,
|
||||
void **cookiep)
|
||||
{
|
||||
int level;
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
xlr_reg_t reg;
|
||||
|
||||
/* FIXME is this the right place to fiddle with PIC? */
|
||||
if (strcmp(device_get_name(child), "uart") == 0) {
|
||||
/* FIXME uart 1? */
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_UART_0_INDEX);
|
||||
xlr_write_reg(mmio, PIC_IRT_0_UART_0, 0x01);
|
||||
xlr_write_reg(mmio, PIC_IRT_1_UART_0, ((1 << 31) | (level << 30) | (1 << 6) | (PIC_UART_0_IRQ)));
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
cpu_establish_hardintr("uart", filt,
|
||||
(driver_intr_t *) intr, (void *)arg, PIC_UART_0_IRQ, flags, cookiep);
|
||||
|
||||
} else if (strcmp(device_get_name(child), "rge") == 0) {
|
||||
int irq;
|
||||
|
||||
/* This is a hack to pass in the irq */
|
||||
irq = (int)ires->__r_i;
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE);
|
||||
xlr_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31));
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
cpu_establish_hardintr("rge", filt, (driver_intr_t *) intr, (void *)arg, irq, flags, cookiep);
|
||||
|
||||
} else if (strcmp(device_get_name(child), "ehci") == 0) {
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE);
|
||||
xlr_write_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31));
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
cpu_establish_hardintr("ehci", filt, (driver_intr_t *) intr, (void *)arg, PIC_USB_IRQ, flags, cookiep);
|
||||
}
|
||||
/*
|
||||
* This causes a panic and looks recursive to me (RRS).
|
||||
* BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt,
|
||||
* intr, arg, cookiep);
|
||||
*/
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Strange hook found in mips/include/bus.h */
|
||||
#ifndef MIPS_BUS_SPACE_PCI
|
||||
#define MIPS_BUS_SPACE_PCI 10
|
||||
#endif
|
||||
|
||||
static struct resource *
|
||||
iodi_alloc_resource(device_t bus, device_t child, int type, int *rid,
|
||||
u_long start, u_long end, u_long count, u_int flags)
|
||||
{
|
||||
struct resource *res = malloc(sizeof(*res), M_DEVBUF, M_WAITOK);
|
||||
int unit;
|
||||
|
||||
#ifdef DEBUG
|
||||
switch (type) {
|
||||
case SYS_RES_IRQ:
|
||||
device_printf(bus, "IRQ resource - for %s %lx-%lx\n",
|
||||
device_get_nameunit(child), start, end);
|
||||
break;
|
||||
|
||||
case SYS_RES_IOPORT:
|
||||
device_printf(bus, "IOPORT resource - for %s %lx-%lx\n",
|
||||
device_get_nameunit(child), start, end);
|
||||
break;
|
||||
|
||||
case SYS_RES_MEMORY:
|
||||
device_printf(bus, "MEMORY resource - for %s %lx-%lx\n",
|
||||
device_get_nameunit(child), start, end);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strcmp(device_get_name(child), "uart") == 0) {
|
||||
if ((unit = device_get_unit(child)) == 0) { /* uart 0 */
|
||||
res->r_bushandle = (xlr_io_base + XLR_IO_UART_0_OFFSET);
|
||||
} else if (unit == 1) {
|
||||
res->r_bushandle = (xlr_io_base + XLR_IO_UART_1_OFFSET);
|
||||
} else
|
||||
printf("%s: Unknown uart unit\n", __FUNCTION__);
|
||||
|
||||
res->r_bustag = uart_bus_space_mem;
|
||||
} else if (strcmp(device_get_name(child), "ehci") == 0) {
|
||||
res->r_bushandle = 0xbef24000;
|
||||
res->r_bustag = (bus_space_tag_t) MIPS_BUS_SPACE_PCI;
|
||||
} else if (strcmp(device_get_name(child), "cfi") == 0) {
|
||||
res->r_bushandle = 0xbc000000;
|
||||
res->r_bustag = 0;
|
||||
}
|
||||
/* res->r_start = *rid; */
|
||||
return (res);
|
||||
}
|
||||
|
||||
static int
|
||||
iodi_activate_resource(device_t bus, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* prototypes */
|
||||
static int iodi_probe(device_t);
|
||||
static int iodi_attach(device_t);
|
||||
static void iodi_identify(driver_t *, device_t);
|
||||
|
||||
int
|
||||
iodi_probe(device_t dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
iodi_identify(driver_t * driver, device_t parent)
|
||||
{
|
||||
|
||||
BUS_ADD_CHILD(parent, 0, "iodi", 0);
|
||||
}
|
||||
|
||||
int
|
||||
iodi_attach(device_t dev)
|
||||
{
|
||||
device_t tmpd;
|
||||
|
||||
/*
|
||||
* Attach each devices
|
||||
*/
|
||||
device_add_child(dev, "uart", 0);
|
||||
device_add_child(dev, "xlr_i2c", 0);
|
||||
|
||||
if (xlr_board_info.usb)
|
||||
device_add_child(dev, "ehci", 0);
|
||||
|
||||
if (xlr_board_info.cfi)
|
||||
device_add_child(dev, "cfi", 0);
|
||||
|
||||
if (xlr_board_info.gmac_block[0].enabled) {
|
||||
tmpd = device_add_child(dev, "rge", 0);
|
||||
device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
|
||||
|
||||
tmpd = device_add_child(dev, "rge", 1);
|
||||
device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
|
||||
|
||||
tmpd = device_add_child(dev, "rge", 2);
|
||||
device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
|
||||
|
||||
tmpd = device_add_child(dev, "rge", 3);
|
||||
device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
|
||||
}
|
||||
if (xlr_board_info.gmac_block[1].enabled) {
|
||||
if (xlr_board_info.gmac_block[1].type == XLR_GMAC) {
|
||||
tmpd = device_add_child(dev, "rge", 4);
|
||||
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
|
||||
|
||||
tmpd = device_add_child(dev, "rge", 5);
|
||||
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
|
||||
|
||||
tmpd = device_add_child(dev, "rge", 6);
|
||||
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
|
||||
|
||||
tmpd = device_add_child(dev, "rge", 7);
|
||||
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
|
||||
} else if (xlr_board_info.gmac_block[1].type == XLR_XGMAC) {
|
||||
#if 0 /* XGMAC not yet */
|
||||
tmpd = device_add_child(dev, "rge", 4);
|
||||
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
|
||||
|
||||
tmpd = device_add_child(dev, "rge", 5);
|
||||
device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
|
||||
#endif
|
||||
} else
|
||||
device_printf(dev, "Unknown type of gmac 1\n");
|
||||
}
|
||||
bus_generic_probe(dev);
|
||||
bus_generic_attach(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static device_method_t iodi_methods[] = {
|
||||
DEVMETHOD(device_probe, iodi_probe),
|
||||
DEVMETHOD(device_attach, iodi_attach),
|
||||
DEVMETHOD(device_identify, iodi_identify),
|
||||
DEVMETHOD(bus_alloc_resource, iodi_alloc_resource),
|
||||
DEVMETHOD(bus_activate_resource, iodi_activate_resource),
|
||||
DEVMETHOD(bus_setup_intr, iodi_setup_intr),
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static driver_t iodi_driver = {
|
||||
"iodi",
|
||||
iodi_methods,
|
||||
1 /* no softc */
|
||||
};
|
||||
static devclass_t iodi_devclass;
|
||||
|
||||
DRIVER_MODULE(iodi, nexus, iodi_driver, iodi_devclass, 0, 0);
|
113
sys/mips/rmi/iomap.h
Normal file
113
sys/mips/rmi/iomap.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 _RMI_IOMAP_H_
|
||||
#define _RMI_IOMAP_H_
|
||||
|
||||
#include <machine/endian.h>
|
||||
#define XLR_DEVICE_REGISTER_BASE 0x1EF00000
|
||||
#define DEFAULT_XLR_IO_BASE 0xffffffffbef00000ULL
|
||||
#define XLR_IO_SIZE 0x1000
|
||||
|
||||
#define XLR_IO_BRIDGE_OFFSET 0x00000
|
||||
|
||||
#define XLR_IO_DDR2_CHN0_OFFSET 0x01000
|
||||
#define XLR_IO_DDR2_CHN1_OFFSET 0x02000
|
||||
#define XLR_IO_DDR2_CHN2_OFFSET 0x03000
|
||||
#define XLR_IO_DDR2_CHN3_OFFSET 0x04000
|
||||
|
||||
#define XLR_IO_RLD2_CHN0_OFFSET 0x05000
|
||||
#define XLR_IO_RLD2_CHN1_OFFSET 0x06000
|
||||
|
||||
#define XLR_IO_SRAM_OFFSET 0x07000
|
||||
|
||||
#define XLR_IO_PIC_OFFSET 0x08000
|
||||
#define XLR_IO_PCIX_OFFSET 0x09000
|
||||
#define XLR_IO_HT_OFFSET 0x0A000
|
||||
|
||||
#define XLR_IO_SECURITY_OFFSET 0x0B000
|
||||
|
||||
#define XLR_IO_GMAC_0_OFFSET 0x0C000
|
||||
#define XLR_IO_GMAC_1_OFFSET 0x0D000
|
||||
#define XLR_IO_GMAC_2_OFFSET 0x0E000
|
||||
#define XLR_IO_GMAC_3_OFFSET 0x0F000
|
||||
|
||||
#define XLR_IO_SPI4_0_OFFSET 0x10000
|
||||
#define XLR_IO_XGMAC_0_OFFSET 0x11000
|
||||
#define XLR_IO_SPI4_1_OFFSET 0x12000
|
||||
#define XLR_IO_XGMAC_1_OFFSET 0x13000
|
||||
|
||||
#define XLR_IO_UART_0_OFFSET 0x14000
|
||||
#define XLR_IO_UART_1_OFFSET 0x15000
|
||||
#define XLR_UART0ADDR (XLR_IO_UART_0_OFFSET+XLR_DEVICE_REGISTER_BASE)
|
||||
|
||||
|
||||
|
||||
#define XLR_IO_I2C_0_OFFSET 0x16000
|
||||
#define XLR_IO_I2C_1_OFFSET 0x17000
|
||||
|
||||
#define XLR_IO_GPIO_OFFSET 0x18000
|
||||
|
||||
#define XLR_IO_FLASH_OFFSET 0x19000
|
||||
|
||||
#define XLR_IO_TB_OFFSET 0x1C000
|
||||
|
||||
#define XLR_IO_GMAC_4_OFFSET 0x20000
|
||||
#define XLR_IO_GMAC_5_OFFSET 0x21000
|
||||
#define XLR_IO_GMAC_6_OFFSET 0x22000
|
||||
#define XLR_IO_GMAC_7_OFFSET 0x23000
|
||||
|
||||
#define XLR_IO_PCIE_0_OFFSET 0x1E000
|
||||
#define XLR_IO_PCIE_1_OFFSET 0x1F000
|
||||
|
||||
#define XLR_IO_USB_0_OFFSET 0x24000
|
||||
#define XLR_IO_USB_1_OFFSET 0x25000
|
||||
|
||||
#define XLR_IO_COMP_OFFSET 0x1d000
|
||||
|
||||
/* Base Address (Virtual) of the PCI Config address space
|
||||
* For now, choose 256M phys in kseg1 = 0xA0000000 + (1<<28)
|
||||
* Config space spans 256 (num of buses) * 256 (num functions) * 256 bytes
|
||||
* ie 1<<24 = 16M
|
||||
*/
|
||||
#define DEFAULT_PCI_CONFIG_BASE 0x18000000
|
||||
#define DEFAULT_HT_TYPE0_CFG_BASE 0x16000000
|
||||
#define DEFAULT_HT_TYPE1_CFG_BASE 0x17000000
|
||||
|
||||
typedef volatile __uint32_t xlr_reg_t;
|
||||
extern unsigned long xlr_io_base;
|
||||
|
||||
#define xlr_io_mmio(offset) ((xlr_reg_t *)(xlr_io_base+(offset)))
|
||||
|
||||
#define xlr_read_reg(base, offset) (__ntohl((base)[(offset)]))
|
||||
#define xlr_write_reg(base, offset, value) ((base)[(offset)] = __htonl((value)))
|
||||
|
||||
extern void on_chip_init(void);
|
||||
|
||||
#endif /* _RMI_IOMAP_H_ */
|
317
sys/mips/rmi/msgring.c
Normal file
317
sys/mips/rmi/msgring.c
Normal file
@ -0,0 +1,317 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
/**********************************************************
|
||||
* -----------------DO NOT EDIT THIS FILE------------------
|
||||
* This file has been autogenerated by the build process
|
||||
* from "msgring.cfg"
|
||||
**********************************************************/
|
||||
|
||||
#include <mips/rmi/msgring.h>
|
||||
|
||||
struct bucket_size bucket_sizes = {
|
||||
{
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 0,
|
||||
32, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 0,
|
||||
0, 32, 32, 32, 32, 32, 0, 32,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 32, 0, 32, 0, 0, 0, 0,
|
||||
128, 0, 0, 0, 128, 0, 0, 0,
|
||||
}
|
||||
};
|
||||
|
||||
struct stn_cc cc_table_cpu_0 = {{
|
||||
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 4, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{0, 2, 4, 4, 4, 4, 0, 2},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 2, 0, 2, 0, 0, 0, 0},
|
||||
{16, 0, 0, 0, 16, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_cpu_1 = {{
|
||||
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{0, 2, 4, 4, 4, 4, 0, 2},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 2, 0, 2, 0, 0, 0, 0},
|
||||
{16, 0, 0, 0, 16, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_cpu_2 = {{
|
||||
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{0, 4, 4, 4, 4, 4, 0, 4},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 0, 4, 0, 0, 0, 0},
|
||||
{16, 0, 0, 0, 16, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_cpu_3 = {{
|
||||
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{0, 4, 4, 4, 4, 4, 0, 4},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 0, 4, 0, 0, 0, 0},
|
||||
{16, 0, 0, 0, 16, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_cpu_4 = {{
|
||||
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{0, 4, 4, 4, 4, 4, 0, 4},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 0, 4, 0, 0, 0, 0},
|
||||
{16, 0, 0, 0, 16, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_cpu_5 = {{
|
||||
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{0, 4, 4, 4, 4, 4, 0, 4},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 0, 4, 0, 0, 0, 0},
|
||||
{16, 0, 0, 0, 16, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_cpu_6 = {{
|
||||
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{0, 4, 4, 4, 4, 4, 0, 4},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 0, 4, 0, 0, 0, 0},
|
||||
{16, 0, 0, 0, 16, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_cpu_7 = {{
|
||||
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2},
|
||||
{2, 2, 2, 2, 2, 2, 2, 0},
|
||||
{0, 4, 4, 4, 4, 4, 0, 4},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 0, 4, 0, 0, 0, 0},
|
||||
{16, 0, 0, 0, 16, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_xgs_0 = {{
|
||||
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_xgs_1 = {{
|
||||
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 4, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_gmac = {{
|
||||
|
||||
{8, 8, 8, 8, 16, 16, 16, 16},
|
||||
{8, 8, 8, 8, 16, 16, 16, 16},
|
||||
{8, 8, 8, 8, 16, 16, 16, 16},
|
||||
{8, 8, 8, 8, 16, 16, 16, 16},
|
||||
{8, 8, 8, 8, 16, 16, 16, 16},
|
||||
{8, 8, 8, 8, 16, 16, 16, 16},
|
||||
{8, 8, 8, 8, 16, 16, 16, 16},
|
||||
{8, 8, 8, 8, 16, 16, 16, 16},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 0, 0, 0, 0, 0, 4},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_dma = {{
|
||||
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc cc_table_sec = {{
|
||||
|
||||
{8, 8, 8, 8, 0, 0, 0, 0},
|
||||
{8, 8, 8, 4, 0, 0, 0, 0},
|
||||
{8, 8, 8, 8, 0, 0, 0, 0},
|
||||
{8, 8, 8, 8, 0, 0, 0, 0},
|
||||
{8, 8, 8, 8, 0, 0, 0, 0},
|
||||
{8, 8, 8, 8, 0, 0, 0, 0},
|
||||
{8, 8, 8, 8, 0, 0, 0, 0},
|
||||
{8, 8, 8, 8, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
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
529
sys/mips/rmi/msgring.h
Executable file
529
sys/mips/rmi/msgring.h
Executable file
@ -0,0 +1,529 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
#ifndef _RMI_MSGRING_H_
|
||||
#define _RMI_MSGRING_H_
|
||||
|
||||
#include <mips/rmi/xlrconfig.h>
|
||||
|
||||
#define MSGRNG_TX_BUF_REG 0
|
||||
#define MSGRNG_RX_BUF_REG 1
|
||||
|
||||
#define MSGRNG_MSG_STATUS_REG 2
|
||||
#define MSGRNG_MSG_CONFIG_REG 3
|
||||
|
||||
#define MSGRNG_MSG_BUCKSIZE_REG 4
|
||||
|
||||
#define MSGRNG_CC_0_REG 16
|
||||
#define MSGRNG_CC_1_REG 17
|
||||
#define MSGRNG_CC_2_REG 18
|
||||
#define MSGRNG_CC_3_REG 19
|
||||
#define MSGRNG_CC_4_REG 20
|
||||
#define MSGRNG_CC_5_REG 21
|
||||
#define MSGRNG_CC_6_REG 22
|
||||
#define MSGRNG_CC_7_REG 23
|
||||
#define MSGRNG_CC_8_REG 24
|
||||
#define MSGRNG_CC_9_REG 25
|
||||
#define MSGRNG_CC_10_REG 26
|
||||
#define MSGRNG_CC_11_REG 27
|
||||
#define MSGRNG_CC_12_REG 28
|
||||
#define MSGRNG_CC_13_REG 29
|
||||
#define MSGRNG_CC_14_REG 30
|
||||
#define MSGRNG_CC_15_REG 31
|
||||
|
||||
#define msgrng_read_status() read_c2_register32(MSGRNG_MSG_STATUS_REG, 0)
|
||||
|
||||
#define msgrng_read_config() read_c2_register32(MSGRNG_MSG_CONFIG_REG, 0)
|
||||
#define msgrng_write_config(value) write_c2_register32(MSGRNG_MSG_CONFIG_REG, 0, value)
|
||||
|
||||
#define msgrng_read_bucksize(bucket) read_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, bucket)
|
||||
#define msgrng_write_bucksize(bucket, value) write_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, bucket, value)
|
||||
|
||||
#define msgrng_read_cc(reg, pri) read_c2_register32(reg, pri)
|
||||
#define msgrng_write_cc(reg, value, pri) write_c2_register32(reg, pri, value)
|
||||
|
||||
#define msgrng_load_rx_msg0() read_c2_register64(MSGRNG_RX_BUF_REG, 0)
|
||||
#define msgrng_load_rx_msg1() read_c2_register64(MSGRNG_RX_BUF_REG, 1)
|
||||
#define msgrng_load_rx_msg2() read_c2_register64(MSGRNG_RX_BUF_REG, 2)
|
||||
#define msgrng_load_rx_msg3() read_c2_register64(MSGRNG_RX_BUF_REG, 3)
|
||||
|
||||
#define msgrng_load_tx_msg0(value) write_c2_register64(MSGRNG_TX_BUF_REG, 0, value)
|
||||
#define msgrng_load_tx_msg1(value) write_c2_register64(MSGRNG_TX_BUF_REG, 1, value)
|
||||
#define msgrng_load_tx_msg2(value) write_c2_register64(MSGRNG_TX_BUF_REG, 2, value)
|
||||
#define msgrng_load_tx_msg3(value) write_c2_register64(MSGRNG_TX_BUF_REG, 3, value)
|
||||
|
||||
/* Station IDs */
|
||||
#define MSGRNG_STNID_CPU0 0x00
|
||||
#define MSGRNG_STNID_CPU1 0x08
|
||||
#define MSGRNG_STNID_CPU2 0x10
|
||||
#define MSGRNG_STNID_CPU3 0x18
|
||||
#define MSGRNG_STNID_CPU4 0x20
|
||||
#define MSGRNG_STNID_CPU5 0x28
|
||||
#define MSGRNG_STNID_CPU6 0x30
|
||||
#define MSGRNG_STNID_CPU7 0x38
|
||||
#define MSGRNG_STNID_XGS0_TX 64
|
||||
#define MSGRNG_STNID_XMAC0_00_TX 64
|
||||
#define MSGRNG_STNID_XMAC0_01_TX 65
|
||||
#define MSGRNG_STNID_XMAC0_02_TX 66
|
||||
#define MSGRNG_STNID_XMAC0_03_TX 67
|
||||
#define MSGRNG_STNID_XMAC0_04_TX 68
|
||||
#define MSGRNG_STNID_XMAC0_05_TX 69
|
||||
#define MSGRNG_STNID_XMAC0_06_TX 70
|
||||
#define MSGRNG_STNID_XMAC0_07_TX 71
|
||||
#define MSGRNG_STNID_XMAC0_08_TX 72
|
||||
#define MSGRNG_STNID_XMAC0_09_TX 73
|
||||
#define MSGRNG_STNID_XMAC0_10_TX 74
|
||||
#define MSGRNG_STNID_XMAC0_11_TX 75
|
||||
#define MSGRNG_STNID_XMAC0_12_TX 76
|
||||
#define MSGRNG_STNID_XMAC0_13_TX 77
|
||||
#define MSGRNG_STNID_XMAC0_14_TX 78
|
||||
#define MSGRNG_STNID_XMAC0_15_TX 79
|
||||
|
||||
#define MSGRNG_STNID_XGS1_TX 80
|
||||
#define MSGRNG_STNID_XMAC1_00_TX 80
|
||||
#define MSGRNG_STNID_XMAC1_01_TX 81
|
||||
#define MSGRNG_STNID_XMAC1_02_TX 82
|
||||
#define MSGRNG_STNID_XMAC1_03_TX 83
|
||||
#define MSGRNG_STNID_XMAC1_04_TX 84
|
||||
#define MSGRNG_STNID_XMAC1_05_TX 85
|
||||
#define MSGRNG_STNID_XMAC1_06_TX 86
|
||||
#define MSGRNG_STNID_XMAC1_07_TX 87
|
||||
#define MSGRNG_STNID_XMAC1_08_TX 88
|
||||
#define MSGRNG_STNID_XMAC1_09_TX 89
|
||||
#define MSGRNG_STNID_XMAC1_10_TX 90
|
||||
#define MSGRNG_STNID_XMAC1_11_TX 91
|
||||
#define MSGRNG_STNID_XMAC1_12_TX 92
|
||||
#define MSGRNG_STNID_XMAC1_13_TX 93
|
||||
#define MSGRNG_STNID_XMAC1_14_TX 94
|
||||
#define MSGRNG_STNID_XMAC1_15_TX 95
|
||||
|
||||
#define MSGRNG_STNID_GMAC 96
|
||||
#define MSGRNG_STNID_GMACJFR_0 96
|
||||
#define MSGRNG_STNID_GMACRFR_0 97
|
||||
#define MSGRNG_STNID_GMACTX0 98
|
||||
#define MSGRNG_STNID_GMACTX1 99
|
||||
#define MSGRNG_STNID_GMACTX2 100
|
||||
#define MSGRNG_STNID_GMACTX3 101
|
||||
#define MSGRNG_STNID_GMACJFR_1 102
|
||||
#define MSGRNG_STNID_GMACRFR_1 103
|
||||
|
||||
#define MSGRNG_STNID_DMA 104
|
||||
#define MSGRNG_STNID_DMA_0 104
|
||||
#define MSGRNG_STNID_DMA_1 105
|
||||
#define MSGRNG_STNID_DMA_2 106
|
||||
#define MSGRNG_STNID_DMA_3 107
|
||||
|
||||
#define MSGRNG_STNID_XGS0FR 112
|
||||
#define MSGRNG_STNID_XMAC0JFR 112
|
||||
#define MSGRNG_STNID_XMAC0RFR 113
|
||||
|
||||
#define MSGRNG_STNID_XGS1FR 114
|
||||
#define MSGRNG_STNID_XMAC1JFR 114
|
||||
#define MSGRNG_STNID_XMAC1RFR 115
|
||||
#define MSGRNG_STNID_SEC 120
|
||||
#define MSGRNG_STNID_SEC0 120
|
||||
#define MSGRNG_STNID_SEC1 121
|
||||
#define MSGRNG_STNID_SEC2 122
|
||||
#define MSGRNG_STNID_SEC3 123
|
||||
#define MSGRNG_STNID_PK0 124
|
||||
#define MSGRNG_STNID_SEC_RSA 124
|
||||
#define MSGRNG_STNID_SEC_RSVD0 125
|
||||
#define MSGRNG_STNID_SEC_RSVD1 126
|
||||
#define MSGRNG_STNID_SEC_RSVD2 127
|
||||
|
||||
#define MSGRNG_STNID_GMAC1 80
|
||||
#define MSGRNG_STNID_GMAC1_FR_0 81
|
||||
#define MSGRNG_STNID_GMAC1_TX0 82
|
||||
#define MSGRNG_STNID_GMAC1_TX1 83
|
||||
#define MSGRNG_STNID_GMAC1_TX2 84
|
||||
#define MSGRNG_STNID_GMAC1_TX3 85
|
||||
#define MSGRNG_STNID_GMAC1_FR_1 87
|
||||
#define MSGRNG_STNID_GMAC0 96
|
||||
#define MSGRNG_STNID_GMAC0_FR_0 97
|
||||
#define MSGRNG_STNID_GMAC0_TX0 98
|
||||
#define MSGRNG_STNID_GMAC0_TX1 99
|
||||
#define MSGRNG_STNID_GMAC0_TX2 100
|
||||
#define MSGRNG_STNID_GMAC0_TX3 101
|
||||
#define MSGRNG_STNID_GMAC0_FR_1 103
|
||||
#define MSGRNG_STNID_CMP_0 108
|
||||
#define MSGRNG_STNID_CMP_1 109
|
||||
#define MSGRNG_STNID_CMP_2 110
|
||||
#define MSGRNG_STNID_CMP_3 111
|
||||
#define MSGRNG_STNID_PCIE_0 116
|
||||
#define MSGRNG_STNID_PCIE_1 117
|
||||
#define MSGRNG_STNID_PCIE_2 118
|
||||
#define MSGRNG_STNID_PCIE_3 119
|
||||
#define MSGRNG_STNID_XLS_PK0 121
|
||||
|
||||
#define MSGRNG_CODE_MAC 0
|
||||
#define MSGRNG_CODE_XGMAC 2
|
||||
#define MSGRNG_CODE_SEC 0
|
||||
#define MSGRNG_CODE_BOOT_WAKEUP 200
|
||||
#define MSGRNG_CODE_SPI4 3
|
||||
|
||||
static inline int
|
||||
msgrng_xgmac_stid_rfr(int id)
|
||||
{
|
||||
return !id ? MSGRNG_STNID_XMAC0RFR : MSGRNG_STNID_XMAC1RFR;
|
||||
}
|
||||
|
||||
static inline int
|
||||
msgrng_xgmac_stid_jfr(int id)
|
||||
{
|
||||
return !id ? MSGRNG_STNID_XMAC0JFR : MSGRNG_STNID_XMAC1JFR;
|
||||
}
|
||||
|
||||
static inline int
|
||||
msgrng_xgmac_stid_tx(int id)
|
||||
{
|
||||
return !id ? MSGRNG_STNID_XMAC0_00_TX : MSGRNG_STNID_XMAC1_00_TX;
|
||||
}
|
||||
|
||||
static inline int
|
||||
msgrng_gmac_stid_rfr(int id)
|
||||
{
|
||||
return (MSGRNG_STNID_GMACRFR_0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
msgrng_gmac_stid_rfr_split_mode(int id)
|
||||
{
|
||||
return ((id >> 1) ? MSGRNG_STNID_GMACRFR_1 : MSGRNG_STNID_GMACRFR_0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
msgrng_gmac_stid_jfr(int id)
|
||||
{
|
||||
return MSGRNG_STNID_GMACJFR_0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
msgrng_gmac_stid_jfr_split_mode(int id)
|
||||
{
|
||||
return ((id >> 1) ? MSGRNG_STNID_GMACJFR_1 : MSGRNG_STNID_GMACJFR_0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
msgrng_gmac_stid_tx(int id)
|
||||
{
|
||||
return (MSGRNG_STNID_GMACTX0 + id);
|
||||
}
|
||||
|
||||
static inline void
|
||||
msgrng_send(unsigned int stid)
|
||||
{
|
||||
__asm__ volatile (
|
||||
".set push\n"
|
||||
".set noreorder\n"
|
||||
"sync\n"
|
||||
// "msgsnd %0\n"
|
||||
"move $8, %0\n"
|
||||
"c2 0x80001\n"
|
||||
".set pop\n"
|
||||
:: "r" (stid):"$8"
|
||||
);
|
||||
}
|
||||
|
||||
static inline void
|
||||
msgrng_receive(unsigned int pri)
|
||||
{
|
||||
__asm__ volatile (
|
||||
".set push\n"
|
||||
".set noreorder\n"
|
||||
// "msgld %0\n"
|
||||
"move $8, %0\n"
|
||||
"c2 0x80002\n"
|
||||
".set pop\n"
|
||||
:: "r" (pri):"$8"
|
||||
);
|
||||
}
|
||||
static inline void
|
||||
msgrng_wait(unsigned int mask)
|
||||
{
|
||||
__asm__ volatile (
|
||||
".set push\n"
|
||||
".set noreorder\n"
|
||||
// "msgwait %0\n"
|
||||
"move $8, %0\n"
|
||||
"c2 0x80003\n"
|
||||
".set pop\n"
|
||||
:: "r" (mask):"$8"
|
||||
);
|
||||
}
|
||||
|
||||
#define msgrng_enable(flags) \
|
||||
do { \
|
||||
__asm__ volatile ( \
|
||||
".set push\n\t" \
|
||||
".set reorder\n\t" \
|
||||
".set noat\n\t" \
|
||||
"mfc0 %0, $12\n\t" \
|
||||
"li $8, 0x40000001\n\t" \
|
||||
"or $1, %0, $8\n\t" \
|
||||
"xori $1, 1\n\t" \
|
||||
".set noreorder\n\t" \
|
||||
"mtc0 $1, $12\n\t" \
|
||||
".set\tpop\n\t" \
|
||||
: "=r" (flags) \
|
||||
: \
|
||||
: "$8" \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
#define msgrng_disable(flags) __asm__ volatile ( \
|
||||
"mtc0 %0, $12" : : "r" (flags))
|
||||
|
||||
#define msgrng_flags_save(flags) msgrng_enable(flags)
|
||||
#define msgrng_flags_restore(flags) msgrng_disable(flags)
|
||||
|
||||
struct msgrng_msg {
|
||||
__uint64_t msg0;
|
||||
__uint64_t msg1;
|
||||
__uint64_t msg2;
|
||||
__uint64_t msg3;
|
||||
};
|
||||
|
||||
static inline void
|
||||
message_send_block_fast(int size, unsigned int code, unsigned int stid,
|
||||
unsigned long long msg0, unsigned long long msg1,
|
||||
unsigned long long msg2, unsigned long long msg3)
|
||||
{
|
||||
__asm__ __volatile__(".set push\n"
|
||||
".set noreorder\n"
|
||||
".set mips64\n"
|
||||
"dmtc2 %1, $0, 0\n"
|
||||
"dmtc2 %2, $0, 1\n"
|
||||
"dmtc2 %3, $0, 2\n"
|
||||
"dmtc2 %4, $0, 3\n"
|
||||
"move $8, %0\n"
|
||||
"1: c2 0x80001\n"
|
||||
"mfc2 $8, $2\n"
|
||||
"andi $8, $8, 0x6\n"
|
||||
"bnez $8, 1b\n"
|
||||
"move $8, %0\n"
|
||||
".set pop\n"
|
||||
:
|
||||
: "r"(((size - 1) << 16) | (code << 8) | stid), "r"(msg0), "r"(msg1), "r"(msg2), "r"(msg3)
|
||||
: "$8"
|
||||
);
|
||||
}
|
||||
|
||||
#define message_receive_fast(bucket, size, code, stid, msg0, msg1, msg2, msg3) \
|
||||
( { unsigned int _status=0, _tmp=0; \
|
||||
msgrng_receive(bucket); \
|
||||
while ( (_status=msgrng_read_status()) & 0x08) ; \
|
||||
_tmp = _status & 0x30; \
|
||||
if (__builtin_expect((!_tmp), 1)) { \
|
||||
(size)=((_status & 0xc0)>>6)+1; \
|
||||
(code)=(_status & 0xff00)>>8; \
|
||||
(stid)=(_status & 0x7f0000)>>16; \
|
||||
(msg0)=msgrng_load_rx_msg0(); \
|
||||
(msg1)=msgrng_load_rx_msg1(); \
|
||||
(msg2)=msgrng_load_rx_msg2(); \
|
||||
(msg3)=msgrng_load_rx_msg3(); \
|
||||
_tmp=0; \
|
||||
} \
|
||||
_tmp; \
|
||||
} )
|
||||
|
||||
static __inline__ int
|
||||
message_send(unsigned int size, unsigned int code,
|
||||
unsigned int stid, struct msgrng_msg *msg)
|
||||
{
|
||||
unsigned int dest = 0;
|
||||
unsigned long long status = 0;
|
||||
int i = 0;
|
||||
|
||||
msgrng_load_tx_msg0(msg->msg0);
|
||||
msgrng_load_tx_msg1(msg->msg1);
|
||||
msgrng_load_tx_msg2(msg->msg2);
|
||||
msgrng_load_tx_msg3(msg->msg3);
|
||||
|
||||
dest = ((size - 1) << 16) | (code << 8) | (stid);
|
||||
|
||||
//dbg_msg("Sending msg<%Lx,%Lx,%Lx,%Lx> to dest = %x\n",
|
||||
//msg->msg0, msg->msg1, msg->msg2, msg->msg3, dest);
|
||||
|
||||
msgrng_send(dest);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
status = msgrng_read_status();
|
||||
//dbg_msg("status = %Lx\n", status);
|
||||
|
||||
if (status & 0x6) {
|
||||
continue;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (i == 16) {
|
||||
if (dest == 0x61)
|
||||
//dbg_msg("Processor %x: Unable to send msg to %llx\n", processor_id(), dest);
|
||||
return status & 0x6;
|
||||
}
|
||||
return msgrng_read_status() & 0x06;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
message_send_retry(unsigned int size, unsigned int code,
|
||||
unsigned int stid, struct msgrng_msg *msg)
|
||||
{
|
||||
int res = 0;
|
||||
int retry = 0;
|
||||
|
||||
for (;;) {
|
||||
res = message_send(size, code, stid, msg);
|
||||
/* retry a pending fail */
|
||||
if (res & 0x02)
|
||||
continue;
|
||||
/* credit fail */
|
||||
if (res & 0x04)
|
||||
retry++;
|
||||
else
|
||||
break;
|
||||
if (retry == 4)
|
||||
return res & 0x06;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
message_receive(int pri, int *size, int *code, int *src_id,
|
||||
struct msgrng_msg *msg)
|
||||
{
|
||||
int res = message_receive_fast(pri, *size, *code, *src_id, msg->msg0, msg->msg1, msg->msg2, msg->msg3);
|
||||
|
||||
#ifdef MSGRING_DUMP_MESSAGES
|
||||
if (!res) {
|
||||
dbg_msg("Received msg <%llx, %llx, %llx, %llx> <%d,%d,%d>\n",
|
||||
msg->msg0, msg->msg1, msg->msg2, msg->msg3,
|
||||
*size, *code, *src_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define MSGRNG_STN_RX_QSIZE 256
|
||||
|
||||
struct stn_cc {
|
||||
unsigned short counters[16][8];
|
||||
};
|
||||
|
||||
struct bucket_size {
|
||||
unsigned short bucket[128];
|
||||
};
|
||||
|
||||
extern struct bucket_size bucket_sizes;
|
||||
|
||||
extern struct stn_cc cc_table_cpu_0;
|
||||
extern struct stn_cc cc_table_cpu_1;
|
||||
extern struct stn_cc cc_table_cpu_2;
|
||||
extern struct stn_cc cc_table_cpu_3;
|
||||
extern struct stn_cc cc_table_cpu_4;
|
||||
extern struct stn_cc cc_table_cpu_5;
|
||||
extern struct stn_cc cc_table_cpu_6;
|
||||
extern struct stn_cc cc_table_cpu_7;
|
||||
extern struct stn_cc cc_table_xgs_0;
|
||||
extern struct stn_cc cc_table_xgs_1;
|
||||
extern struct stn_cc cc_table_gmac;
|
||||
extern struct stn_cc cc_table_dma;
|
||||
extern struct stn_cc cc_table_sec;
|
||||
|
||||
extern struct bucket_size xls_bucket_sizes;
|
||||
|
||||
extern struct stn_cc xls_cc_table_cpu_0;
|
||||
extern struct stn_cc xls_cc_table_cpu_1;
|
||||
extern struct stn_cc xls_cc_table_cpu_2;
|
||||
extern struct stn_cc xls_cc_table_cpu_3;
|
||||
extern struct stn_cc xls_cc_table_gmac0;
|
||||
extern struct stn_cc xls_cc_table_gmac1;
|
||||
extern struct stn_cc xls_cc_table_cmp;
|
||||
extern struct stn_cc xls_cc_table_pcie;
|
||||
extern struct stn_cc xls_cc_table_dma;
|
||||
extern struct stn_cc xls_cc_table_sec;
|
||||
|
||||
|
||||
#define msgrng_access_save(lock, mflags) do { \
|
||||
if (rmi_spin_mutex_safe) mtx_lock_spin(lock); \
|
||||
msgrng_flags_save(mflags); \
|
||||
}while(0)
|
||||
|
||||
#define msgrng_access_restore(lock, mflags) do { \
|
||||
msgrng_flags_restore(mflags); \
|
||||
if (rmi_spin_mutex_safe) mtx_unlock_spin(lock); \
|
||||
}while(0)
|
||||
|
||||
#define msgrng_access_enable(mflags) do { \
|
||||
critical_enter(); \
|
||||
msgrng_flags_save(mflags); \
|
||||
} while(0)
|
||||
|
||||
#define msgrng_access_disable(mflags) do { \
|
||||
msgrng_flags_restore(mflags); \
|
||||
critical_exit(); \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* NOTE: this is not stationid/8, ie the station numbers below are just
|
||||
* for internal use
|
||||
*/
|
||||
enum {
|
||||
TX_STN_CPU_0,
|
||||
TX_STN_CPU_1,
|
||||
TX_STN_CPU_2,
|
||||
TX_STN_CPU_3,
|
||||
TX_STN_CPU_4,
|
||||
TX_STN_CPU_5,
|
||||
TX_STN_CPU_6,
|
||||
TX_STN_CPU_7,
|
||||
TX_STN_GMAC,
|
||||
TX_STN_DMA,
|
||||
TX_STN_XGS_0,
|
||||
TX_STN_XGS_1,
|
||||
TX_STN_SAE,
|
||||
TX_STN_GMAC0,
|
||||
TX_STN_GMAC1,
|
||||
TX_STN_CDE,
|
||||
TX_STN_PCIE,
|
||||
TX_STN_INVALID,
|
||||
MAX_TX_STNS
|
||||
};
|
||||
|
||||
extern int
|
||||
register_msgring_handler(int major,
|
||||
void (*action) (int, int, int, int, struct msgrng_msg *, void *),
|
||||
void *dev_id);
|
||||
extern void xlr_msgring_cpu_init(void);
|
||||
|
||||
extern void xlr_msgring_config(void);
|
||||
|
||||
#define cpu_to_msgring_bucket(cpu) ((((cpu) >> 2)<<3)|((cpu) & 0x03))
|
||||
|
||||
#endif
|
217
sys/mips/rmi/msgring_xls.c
Normal file
217
sys/mips/rmi/msgring_xls.c
Normal file
@ -0,0 +1,217 @@
|
||||
/**********************************************************
|
||||
* -----------------DO NOT EDIT THIS FILE------------------
|
||||
* This file has been autogenerated by the build process
|
||||
* from "msgring_xls.cfg"
|
||||
**********************************************************/
|
||||
|
||||
#include <mips/rmi/msgring.h>
|
||||
|
||||
struct bucket_size xls_bucket_sizes = {
|
||||
{32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 32, 32, 32, 32, 32, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 32, 32, 32, 32, 32, 0, 0,
|
||||
64, 64, 64, 64, 32, 32, 32, 32,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
128, 128, 0, 0, 0, 0, 0, 0,
|
||||
}
|
||||
};
|
||||
|
||||
struct stn_cc xls_cc_table_cpu_0 = {{
|
||||
{1, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 8, 0, 0, 0, 0},
|
||||
{0, 0, 0, 8, 0, 0, 0, 0},
|
||||
{0, 0, 0, 8, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 8, 8, 8, 8, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 8, 8, 8, 8, 0, 0},
|
||||
{16, 16, 16, 16, 16, 16, 16, 16},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{32, 32, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc xls_cc_table_cpu_1 = {{
|
||||
{1, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 8, 8, 8, 8, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 8, 8, 8, 8, 0, 0},
|
||||
{16, 16, 16, 16, 16, 16, 16, 16},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{32, 32, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc xls_cc_table_cpu_2 = {{
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 8, 8, 8, 8, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 8, 8, 8, 8, 0, 0},
|
||||
{16, 16, 16, 16, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{32, 32, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc xls_cc_table_cpu_3 = {{
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 8, 8, 8, 8, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 4, 8, 8, 8, 8, 0, 0},
|
||||
{16, 16, 16, 16, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{32, 32, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc xls_cc_table_gmac0 = {{
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 8, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 8, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc xls_cc_table_gmac1 = {{
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{8, 8, 8, 8, 8, 8, 8, 8},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 8, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 8, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc xls_cc_table_dma = {{
|
||||
{4, 4, 4, 4, 4, 4, 4, 4},
|
||||
{4, 4, 4, 2, 4, 4, 4, 4},
|
||||
{4, 4, 4, 2, 4, 4, 4, 4},
|
||||
{4, 4, 4, 2, 4, 4, 4, 4},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc xls_cc_table_cmp = {{
|
||||
{4, 4, 4, 4, 4, 4, 4, 4},
|
||||
{4, 4, 4, 2, 4, 4, 4, 4},
|
||||
{4, 4, 4, 2, 4, 4, 4, 4},
|
||||
{4, 4, 4, 2, 4, 4, 4, 4},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc xls_cc_table_pcie = {{
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
||||
|
||||
struct stn_cc xls_cc_table_sec = {{
|
||||
{6, 8, 8, 8, 0, 0, 0, 0},
|
||||
{8, 8, 8, 4, 0, 0, 0, 0},
|
||||
{8, 8, 8, 4, 0, 0, 0, 0},
|
||||
{8, 8, 8, 4, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}};
|
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;
|
||||
}
|
||||
|
330
sys/mips/rmi/on_chip.c
Normal file
330
sys/mips/rmi/on_chip.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <machine/reg.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/mips_opcode.h>
|
||||
|
||||
#include <machine/param.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <mips/rmi/interrupt.h>
|
||||
#include <mips/rmi/msgring.h>
|
||||
#include <mips/rmi/iomap.h>
|
||||
#include <mips/rmi/debug.h>
|
||||
#include <mips/rmi/pic.h>
|
||||
#include <mips/rmi/board.h>
|
||||
|
||||
void
|
||||
disable_msgring_int(void *arg);
|
||||
void
|
||||
enable_msgring_int(void *arg);
|
||||
|
||||
/* definitions */
|
||||
struct tx_stn_handler {
|
||||
void (*action) (int, int, int, int, struct msgrng_msg *, void *);
|
||||
void *dev_id;
|
||||
};
|
||||
|
||||
/* globals */
|
||||
static struct tx_stn_handler tx_stn_handlers[MAX_TX_STNS];
|
||||
|
||||
#define MSGRNG_CC_INIT_CPU_DEST(dest, counter) \
|
||||
do { \
|
||||
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][0], 0 ); \
|
||||
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][1], 1 ); \
|
||||
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][2], 2 ); \
|
||||
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][3], 3 ); \
|
||||
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][4], 4 ); \
|
||||
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][5], 5 ); \
|
||||
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][6], 6 ); \
|
||||
msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][7], 7 ); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/* make this a read/write spinlock */
|
||||
static struct mtx msgrng_lock;
|
||||
static int msgring_int_enabled;
|
||||
struct mtx xlr_pic_lock;
|
||||
|
||||
static int msgring_pop_num_buckets;
|
||||
static uint32_t msgring_pop_bucket_mask;
|
||||
static int msgring_int_type;
|
||||
static int msgring_watermark_count;
|
||||
static uint32_t msgring_thread_mask;
|
||||
|
||||
uint32_t msgrng_msg_cycles = 0;
|
||||
|
||||
int xlr_counters[MAXCPU][XLR_MAX_COUNTERS] __aligned(XLR_CACHELINE_SIZE);
|
||||
|
||||
void xlr_msgring_handler(struct trapframe *);
|
||||
|
||||
void
|
||||
xlr_msgring_cpu_init(void)
|
||||
{
|
||||
struct stn_cc *cc_config;
|
||||
struct bucket_size *bucket_sizes;
|
||||
int id;
|
||||
unsigned long flags;
|
||||
|
||||
/* if not thread 0 */
|
||||
if (xlr_thr_id() != 0)
|
||||
return;
|
||||
id = xlr_cpu_id();
|
||||
|
||||
bucket_sizes = xlr_board_info.bucket_sizes;
|
||||
cc_config = xlr_board_info.credit_configs[id];
|
||||
|
||||
msgrng_flags_save(flags);
|
||||
|
||||
/*
|
||||
* Message Stations are shared among all threads in a cpu core
|
||||
* Assume, thread 0 on all cores are always active when more than 1
|
||||
* thread is active in a core
|
||||
*/
|
||||
msgrng_write_bucksize(0, bucket_sizes->bucket[id * 8 + 0]);
|
||||
msgrng_write_bucksize(1, bucket_sizes->bucket[id * 8 + 1]);
|
||||
msgrng_write_bucksize(2, bucket_sizes->bucket[id * 8 + 2]);
|
||||
msgrng_write_bucksize(3, bucket_sizes->bucket[id * 8 + 3]);
|
||||
msgrng_write_bucksize(4, bucket_sizes->bucket[id * 8 + 4]);
|
||||
msgrng_write_bucksize(5, bucket_sizes->bucket[id * 8 + 5]);
|
||||
msgrng_write_bucksize(6, bucket_sizes->bucket[id * 8 + 6]);
|
||||
msgrng_write_bucksize(7, bucket_sizes->bucket[id * 8 + 7]);
|
||||
|
||||
MSGRNG_CC_INIT_CPU_DEST(0, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(1, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(2, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(3, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(4, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(5, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(6, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(7, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(8, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(9, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(10, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(11, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(12, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(13, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(14, cc_config->counters);
|
||||
MSGRNG_CC_INIT_CPU_DEST(15, cc_config->counters);
|
||||
|
||||
msgrng_flags_restore(flags);
|
||||
}
|
||||
|
||||
void
|
||||
xlr_msgring_config(void)
|
||||
{
|
||||
msgring_int_type = 0x02;
|
||||
msgring_pop_num_buckets = 8;
|
||||
msgring_pop_bucket_mask = 0xff;
|
||||
|
||||
msgring_watermark_count = 1;
|
||||
msgring_thread_mask = 0x01;
|
||||
/* printf("[%s]: int_type = 0x%x, pop_num_buckets=%d, pop_bucket_mask=%x" */
|
||||
/* "watermark_count=%d, thread_mask=%x\n", __FUNCTION__, */
|
||||
/* msgring_int_type, msgring_pop_num_buckets, msgring_pop_bucket_mask, */
|
||||
/* msgring_watermark_count, msgring_thread_mask); */
|
||||
}
|
||||
|
||||
void
|
||||
xlr_msgring_handler(struct trapframe *tf)
|
||||
{
|
||||
unsigned long mflags;
|
||||
int bucket = 0;
|
||||
int size = 0, code = 0, rx_stid = 0, tx_stid = 0;
|
||||
struct msgrng_msg msg;
|
||||
unsigned int bucket_empty_bm = 0;
|
||||
unsigned int status = 0;
|
||||
|
||||
xlr_inc_counter(MSGRNG_INT);
|
||||
/* TODO: not necessary to disable preemption */
|
||||
msgrng_flags_save(mflags);
|
||||
|
||||
/* First Drain all the high priority messages */
|
||||
for (;;) {
|
||||
bucket_empty_bm = (msgrng_read_status() >> 24) & msgring_pop_bucket_mask;
|
||||
|
||||
/* all buckets empty, break */
|
||||
if (bucket_empty_bm == msgring_pop_bucket_mask)
|
||||
break;
|
||||
|
||||
for (bucket = 0; bucket < msgring_pop_num_buckets; bucket++) {
|
||||
uint32_t cycles = 0;
|
||||
|
||||
if ((bucket_empty_bm & (1 << bucket)) /* empty */ )
|
||||
continue;
|
||||
|
||||
status = message_receive(bucket, &size, &code, &rx_stid, &msg);
|
||||
if (status)
|
||||
continue;
|
||||
|
||||
xlr_inc_counter(MSGRNG_MSG);
|
||||
msgrng_msg_cycles = mips_rd_count();
|
||||
cycles = msgrng_msg_cycles;
|
||||
|
||||
tx_stid = xlr_board_info.msgmap[rx_stid];
|
||||
|
||||
if (!tx_stn_handlers[tx_stid].action) {
|
||||
printf("[%s]: No Handler for message from stn_id=%d, bucket=%d, "
|
||||
"size=%d, msg0=%llx, dropping message\n",
|
||||
__FUNCTION__, tx_stid, bucket, size, msg.msg0);
|
||||
} else {
|
||||
//printf("[%s]: rx_stid = %d\n", __FUNCTION__, rx_stid);
|
||||
msgrng_flags_restore(mflags);
|
||||
(*tx_stn_handlers[tx_stid].action) (bucket, size, code, rx_stid,
|
||||
&msg, tx_stn_handlers[tx_stid].dev_id);
|
||||
msgrng_flags_save(mflags);
|
||||
}
|
||||
xlr_set_counter(MSGRNG_MSG_CYCLES, (read_c0_count() - cycles));
|
||||
}
|
||||
}
|
||||
|
||||
xlr_set_counter(MSGRNG_EXIT_STATUS, msgrng_read_status());
|
||||
|
||||
msgrng_flags_restore(mflags);
|
||||
|
||||
//dbg_msg("OUT irq=%d\n", irq);
|
||||
|
||||
/* Call the msg callback */
|
||||
}
|
||||
|
||||
void
|
||||
enable_msgring_int(void *arg)
|
||||
{
|
||||
unsigned long mflags = 0;
|
||||
|
||||
msgrng_access_save(&msgrng_lock, mflags);
|
||||
/* enable the message ring interrupts */
|
||||
msgrng_write_config((msgring_watermark_count << 24) | (IRQ_MSGRING << 16)
|
||||
| (msgring_thread_mask << 8) | msgring_int_type);
|
||||
msgrng_access_restore(&msgrng_lock, mflags);
|
||||
}
|
||||
|
||||
void
|
||||
disable_msgring_int(void *arg)
|
||||
{
|
||||
unsigned long mflags = 0;
|
||||
uint32_t config;
|
||||
|
||||
msgrng_access_save(&msgrng_lock, mflags);
|
||||
config = msgrng_read_config();
|
||||
config &= ~0x3;
|
||||
msgrng_write_config(config);
|
||||
msgrng_access_restore(&msgrng_lock, mflags);
|
||||
}
|
||||
|
||||
extern void platform_prep_smp_launch(void);
|
||||
extern void msgring_process_fast_intr(void *arg);
|
||||
|
||||
int
|
||||
register_msgring_handler(int major,
|
||||
void (*action) (int, int, int, int, struct msgrng_msg *, void *),
|
||||
void *dev_id)
|
||||
{
|
||||
void *cookie; /* FIXME - use? */
|
||||
|
||||
if (major >= MAX_TX_STNS)
|
||||
return 1;
|
||||
|
||||
//dbg_msg("major=%d, action=%p, dev_id=%p\n", major, action, dev_id);
|
||||
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_lock_spin(&msgrng_lock);
|
||||
tx_stn_handlers[major].action = action;
|
||||
tx_stn_handlers[major].dev_id = dev_id;
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_unlock_spin(&msgrng_lock);
|
||||
|
||||
if (xlr_test_and_set(&msgring_int_enabled)) {
|
||||
platform_prep_smp_launch();
|
||||
|
||||
cpu_establish_hardintr("msgring", (driver_filter_t *) NULL,
|
||||
(driver_intr_t *) msgring_process_fast_intr,
|
||||
NULL, IRQ_MSGRING, INTR_TYPE_NET | INTR_FAST, &cookie);
|
||||
|
||||
/* configure the msgring interrupt on cpu 0 */
|
||||
enable_msgring_int(NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pic_init(void)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
int i = 0;
|
||||
int level;
|
||||
|
||||
dbg_msg("Initializing PIC...\n");
|
||||
for (i = 0; i < PIC_NUM_IRTS; i++) {
|
||||
|
||||
level = PIC_IRQ_IS_EDGE_TRIGGERED(i);
|
||||
|
||||
/* Bind all PIC irqs to cpu 0 */
|
||||
xlr_write_reg(mmio, PIC_IRT_0_BASE + i, 0x01);
|
||||
|
||||
/*
|
||||
* Use local scheduling and high polarity for all IRTs
|
||||
* Invalidate all IRTs, by default
|
||||
*/
|
||||
xlr_write_reg(mmio, PIC_IRT_1_BASE + i, (level << 30) | (1 << 6) | (PIC_IRQ_BASE + i));
|
||||
}
|
||||
dbg_msg("PIC init now done\n");
|
||||
}
|
||||
|
||||
void
|
||||
on_chip_init(void)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
|
||||
/* Set xlr_io_base to the run time value */
|
||||
mtx_init(&msgrng_lock, "msgring", NULL, MTX_SPIN | MTX_RECURSE);
|
||||
mtx_init(&xlr_pic_lock, "pic", NULL, MTX_SPIN);
|
||||
|
||||
xlr_board_info_setup();
|
||||
|
||||
msgring_int_enabled = 0;
|
||||
|
||||
xlr_msgring_config();
|
||||
pic_init();
|
||||
|
||||
xlr_msgring_cpu_init();
|
||||
|
||||
for (i = 0; i < MAXCPU; i++)
|
||||
for (j = 0; j < XLR_MAX_COUNTERS; j++)
|
||||
atomic_set_int(&xlr_counters[i][j], 0);
|
||||
}
|
357
sys/mips/rmi/pcibus.c
Normal file
357
sys/mips/rmi/pcibus.c
Normal file
@ -0,0 +1,357 @@
|
||||
/*-
|
||||
* Copyright (c) 1997, Stefan Esser <se@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice unmodified, this list of conditions, and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/alpha/pci/pcibus.c,v 1.36 2005/01/05 20:05:52 imp Exp $");
|
||||
|
||||
#include "opt_isa.h"
|
||||
|
||||
#define __RMAN_RESOURCE_VISIBLE
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <sys/interrupt.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <mips/rmi/iomap.h>
|
||||
#include <mips/rmi/pic.h>
|
||||
#include <mips/rmi/shared_structs.h>
|
||||
#include <mips/rmi/board.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <machine/resource.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <mips/rmi/pcibus.h>
|
||||
/*
|
||||
static void bridge_pcix_ack(void *);
|
||||
static void bridge_pcie_ack(void *);
|
||||
static void pic_pcix_ack(void *);
|
||||
static void pic_pcie_ack(void *);
|
||||
*/
|
||||
|
||||
extern vm_map_t kernel_map;
|
||||
vm_offset_t kmem_alloc_nofault(vm_map_t map, vm_size_t size);
|
||||
|
||||
|
||||
int
|
||||
mips_pci_route_interrupt(device_t bus, device_t dev, int pin)
|
||||
{
|
||||
/*
|
||||
* Validate requested pin number.
|
||||
*/
|
||||
if ((pin < 1) || (pin > 4))
|
||||
return (255);
|
||||
|
||||
if (xlr_board_info.is_xls) {
|
||||
switch (pin) {
|
||||
case 1:
|
||||
return PIC_PCIE_LINK0_IRQ;
|
||||
case 2:
|
||||
return PIC_PCIE_LINK1_IRQ;
|
||||
case 3:
|
||||
return PIC_PCIE_LINK2_IRQ;
|
||||
case 4:
|
||||
return PIC_PCIE_LINK3_IRQ;
|
||||
}
|
||||
} else {
|
||||
if (pin == 1) {
|
||||
return (16);
|
||||
}
|
||||
}
|
||||
|
||||
return (255);
|
||||
}
|
||||
|
||||
static struct rman irq_rman, port_rman, mem_rman;
|
||||
|
||||
/*
|
||||
static void bridge_pcix_ack(void *arg)
|
||||
{
|
||||
xlr_read_reg(xlr_io_mmio(XLR_IO_PCIX_OFFSET), 0x140 >> 2);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
static void bridge_pcie_ack(void *arg)
|
||||
{
|
||||
int irq = (int)arg;
|
||||
uint32_t reg;
|
||||
xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET);
|
||||
|
||||
switch (irq) {
|
||||
case PIC_PCIE_LINK0_IRQ : reg = PCIE_LINK0_MSI_STATUS; break;
|
||||
case PIC_PCIE_LINK1_IRQ : reg = PCIE_LINK1_MSI_STATUS; break;
|
||||
case PIC_PCIE_LINK2_IRQ : reg = PCIE_LINK2_MSI_STATUS; break;
|
||||
case PIC_PCIE_LINK3_IRQ : reg = PCIE_LINK3_MSI_STATUS; break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
xlr_write_reg(pcie_mmio_le, reg>>2, 0xffffffff);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
static void pic_pcix_ack(void *none)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
xlr_write_reg(mmio, PIC_INT_ACK, (1 << PIC_IRT_PCIX_INDEX));
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
static void pic_pcie_ack(void *arg)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
int irq = (int) arg;
|
||||
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
mips_platform_pci_setup_intr(device_t dev, device_t child,
|
||||
struct resource *irq, int flags,
|
||||
driver_filter_t * filt,
|
||||
driver_intr_t * intr, void *arg,
|
||||
void **cookiep)
|
||||
{
|
||||
int level;
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
int error = 0;
|
||||
int xlrirq;
|
||||
|
||||
error = rman_activate_resource(irq);
|
||||
if (error)
|
||||
return error;
|
||||
if (rman_get_start(irq) != rman_get_end(irq)) {
|
||||
device_printf(dev, "Interrupt allocation %lu != %lu\n",
|
||||
rman_get_start(irq), rman_get_end(irq));
|
||||
return EINVAL;
|
||||
}
|
||||
xlrirq = rman_get_start(irq);
|
||||
if (strcmp(device_get_name(dev), "pcib") != 0)
|
||||
return 0;
|
||||
|
||||
if (xlr_board_info.is_xls == 0) {
|
||||
|
||||
if (rmi_spin_mutex_safe) mtx_lock_spin(&xlr_pic_lock);
|
||||
level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_PCIX_INDEX);
|
||||
xlr_write_reg(mmio, PIC_IRT_0_PCIX, 0x01);
|
||||
xlr_write_reg(mmio, PIC_IRT_1_PCIX, ((1 << 31) | (level << 30) |
|
||||
(1 << 6) | (PIC_PCIX_IRQ)));
|
||||
if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock);
|
||||
cpu_establish_hardintr(device_get_name(child), filt,
|
||||
(driver_intr_t *) intr, (void *)arg, PIC_PCIX_IRQ, flags, cookiep);
|
||||
|
||||
} else {
|
||||
if (rmi_spin_mutex_safe) mtx_lock_spin(&xlr_pic_lock);
|
||||
xlr_write_reg(mmio, PIC_IRT_0_BASE + xlrirq - PIC_IRQ_BASE, 0x01);
|
||||
xlr_write_reg(mmio, PIC_IRT_1_BASE + xlrirq - PIC_IRQ_BASE,
|
||||
((1 << 31) | (1 << 30) | (1 << 6) | xlrirq));
|
||||
if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock);
|
||||
|
||||
if (flags & INTR_FAST)
|
||||
cpu_establish_hardintr(device_get_name(child), filt,
|
||||
(driver_intr_t *) intr, (void *)arg, xlrirq, flags, cookiep);
|
||||
else
|
||||
cpu_establish_hardintr(device_get_name(child), filt,
|
||||
(driver_intr_t *) intr, (void *)arg, xlrirq, flags, cookiep);
|
||||
|
||||
|
||||
}
|
||||
return bus_generic_setup_intr(dev, child, irq, flags, filt, intr,
|
||||
arg, cookiep);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mips_platform_pci_teardown_intr(device_t dev, device_t child,
|
||||
struct resource *irq, void *cookie);
|
||||
int
|
||||
mips_platform_pci_teardown_intr(device_t dev, device_t child,
|
||||
struct resource *irq, void *cookie)
|
||||
{
|
||||
if (strcmp(device_get_name(child), "pci") == 0) {
|
||||
/* if needed reprogram the pic to clear pcix related entry */
|
||||
}
|
||||
return bus_generic_teardown_intr(dev, child, irq, cookie);
|
||||
}
|
||||
|
||||
void
|
||||
pci_init_resources(void)
|
||||
{
|
||||
irq_rman.rm_start = 0;
|
||||
irq_rman.rm_end = 255;
|
||||
irq_rman.rm_type = RMAN_ARRAY;
|
||||
irq_rman.rm_descr = "PCI Mapped Interrupts";
|
||||
if (rman_init(&irq_rman)
|
||||
|| rman_manage_region(&irq_rman, 0, 255))
|
||||
panic("pci_init_resources irq_rman");
|
||||
|
||||
port_rman.rm_start = 0;
|
||||
port_rman.rm_end = ~0u;
|
||||
port_rman.rm_type = RMAN_ARRAY;
|
||||
port_rman.rm_descr = "I/O ports";
|
||||
if (rman_init(&port_rman)
|
||||
|| rman_manage_region(&port_rman, 0x10000000, 0x1fffffff))
|
||||
panic("pci_init_resources port_rman");
|
||||
|
||||
mem_rman.rm_start = 0;
|
||||
mem_rman.rm_end = ~0u;
|
||||
mem_rman.rm_type = RMAN_ARRAY;
|
||||
mem_rman.rm_descr = "I/O memory";
|
||||
if (rman_init(&mem_rman)
|
||||
|| rman_manage_region(&mem_rman, 0xd0000000, 0xdfffffff))
|
||||
panic("pci_init_resources mem_rman");
|
||||
}
|
||||
|
||||
/* hack from bus.h in mips/include/bus.h */
|
||||
#ifndef MIPS_BUS_SPACE_PCI
|
||||
#define MIPS_BUS_SPACE_PCI 10
|
||||
#endif
|
||||
|
||||
struct resource *
|
||||
xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
|
||||
u_long start, u_long end, u_long count, u_int flags)
|
||||
{
|
||||
struct rman *rm;
|
||||
struct resource *rv;
|
||||
vm_offset_t va;
|
||||
int needactivate = flags & RF_ACTIVE;
|
||||
|
||||
#if 0
|
||||
device_printf(bus, "xlr_pci_alloc_resource : child %s, type %d, start %lx end %lx, count %lx, flags %x\n",
|
||||
device_get_nameunit(child), type, start, end, count, flags);
|
||||
#endif
|
||||
|
||||
switch (type) {
|
||||
case SYS_RES_IRQ:
|
||||
rm = &irq_rman;
|
||||
break;
|
||||
|
||||
case SYS_RES_IOPORT:
|
||||
rm = &port_rman;
|
||||
break;
|
||||
|
||||
case SYS_RES_MEMORY:
|
||||
rm = &mem_rman;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = rman_reserve_resource(rm, start, end, count, flags, child);
|
||||
if (rv == 0)
|
||||
return 0;
|
||||
|
||||
rman_set_bustag(rv, (bus_space_tag_t) MIPS_BUS_SPACE_PCI);
|
||||
rman_set_rid(rv, *rid);
|
||||
|
||||
if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
|
||||
/*
|
||||
* if ((start + count) > (2 << 28)) { va_start =
|
||||
* kmem_alloc_nofault(kernel_map, count); }
|
||||
*/
|
||||
/*
|
||||
* This called for pmap_map_uncached, but the pmap_map calls
|
||||
* pmap_kenter which does a is_cacheable_mem() check and
|
||||
* thus sets the PTE_UNCACHED bit. Hopefully this will work
|
||||
* for this guy... RRS
|
||||
*/
|
||||
/* va = pmap_map(&va_start, start, start + count, 0); */
|
||||
va = (vm_offset_t)pmap_mapdev(start, start + count);
|
||||
rman_set_bushandle(rv, va);
|
||||
/* bushandle is same as virtual addr */
|
||||
rman_set_virtual(rv, (void *)va);
|
||||
rman_set_bustag(rv, (bus_space_tag_t) MIPS_BUS_SPACE_PCI);
|
||||
}
|
||||
if (needactivate) {
|
||||
if (bus_activate_resource(child, type, *rid, rv)) {
|
||||
rman_release_resource(rv);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
return (rman_deactivate_resource(r));
|
||||
}
|
||||
|
||||
/* now in pci.c
|
||||
int
|
||||
pci_activate_resource(device_t bus, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
return (rman_activate_resource(r));
|
||||
}
|
||||
|
||||
int
|
||||
pci_release_resource(device_t bus, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
return (rman_release_resource(r));
|
||||
}
|
||||
*/
|
||||
|
||||
struct rman *
|
||||
pci_get_rman(device_t dev, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case SYS_RES_IOPORT:
|
||||
return &port_rman;
|
||||
|
||||
case SYS_RES_MEMORY:
|
||||
return &mem_rman;
|
||||
|
||||
case SYS_RES_IRQ:
|
||||
return &irq_rman;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
62
sys/mips/rmi/pcibus.h
Normal file
62
sys/mips/rmi/pcibus.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/sys/alpha/pci/pcibus.h,v 1.5 2002/02/28 18:18:41 gallatin Exp $
|
||||
*/
|
||||
#define DEFAULT_PCI_CONFIG_BASE 0x18000000
|
||||
|
||||
#define MSI_MIPS_ADDR_BASE 0xfee00000
|
||||
|
||||
|
||||
#define PCIE_LINK0_MSI_STATUS 0x90
|
||||
#define PCIE_LINK1_MSI_STATUS 0x94
|
||||
#define PCIE_LINK2_MSI_STATUS 0x190
|
||||
#define PCIE_LINK3_MSI_STATUS 0x194
|
||||
|
||||
void pci_init_resources(void);
|
||||
struct resource *
|
||||
xlr_pci_alloc_resource(device_t bus, device_t child,
|
||||
int type, int *rid,
|
||||
u_long start, u_long end, u_long count,
|
||||
u_int flags);
|
||||
int
|
||||
pci_activate_resource(device_t bus, device_t child, int type, int rid,
|
||||
struct resource *r);
|
||||
int
|
||||
pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
|
||||
struct resource *r);
|
||||
int
|
||||
pci_release_resource(device_t bus, device_t child, int type, int rid,
|
||||
struct resource *r);
|
||||
struct rman *pci_get_rman(device_t dev, int type);
|
||||
|
||||
int
|
||||
mips_platform_pci_setup_intr(device_t dev, device_t child,
|
||||
struct resource *irq, int flags,
|
||||
driver_filter_t * filt,
|
||||
driver_intr_t * intr, void *arg,
|
||||
void **cookiep);
|
||||
int
|
||||
mips_pci_route_interrupt(device_t bus, device_t dev, int pin);
|
183
sys/mips/rmi/perfmon.h
Normal file
183
sys/mips/rmi/perfmon.h
Normal file
@ -0,0 +1,183 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
|
||||
#ifndef PERFMON_H
|
||||
#define PERFMON_H
|
||||
|
||||
#include <mips/rmi/perfmon_xlrconfig.h>
|
||||
|
||||
/*
|
||||
* category events reported by the perfmon library
|
||||
*/
|
||||
enum event_category_t {
|
||||
PERF_CP0_COUNTER = 1, PERF_CP2_CREDITS, PERF_L2_COUNTER,
|
||||
PERF_SBC_COUNTER, PERF_SBC_CREDITS, PERF_GMAC0_COUNTER, PERF_GMAC1_COUNTER,
|
||||
PERF_GMAC2_COUNTER, PERF_GMAC_STAT_COM, PERF_GMAC_STAT_TX,
|
||||
PERF_GMAC_STAT_RX, PERF_DRAM_COUNTER, PERF_PARAMETER_CONF = 127};
|
||||
|
||||
|
||||
enum perf_param_t {
|
||||
PERF_CPU_SAMPLING_INTERVAL, PERF_SYS_SAMPLING_INTERVAL, PERF_CC_SAMPLE_RATE, PERF_CP0_FLAGS
|
||||
};
|
||||
|
||||
#define CPO_EVENTS_TEMPLATE 0x06 /* enable kernel and user events */
|
||||
|
||||
#define PERFMON_ACTIVE_MAGIC 0xc001
|
||||
#define PERFMON_ENABLED_MAGIC 0xb007
|
||||
#define PERFMON_INITIAL_GENERATION 0x0101
|
||||
|
||||
#define PERFMON_SERVER_PORT 7007
|
||||
|
||||
enum system_bridge_credits_t {
|
||||
PCIX_CREDITS, HT_CREDITS, GIO_CREDITS, OTHER_CREDITS
|
||||
};
|
||||
|
||||
struct perf_config_data {
|
||||
uint16_t magic; /* monitor start when this is initialized */
|
||||
uint16_t generation; /* incremented when the config changes */
|
||||
uint16_t flags;
|
||||
uint16_t cc_sample_rate;/* rate at which credit counters are sampled
|
||||
* relative to sampling_rate */
|
||||
uint32_t sampling_rate; /* rate at which events are sampled */
|
||||
uint32_t cc_register_mask; /* credit counters registers to be
|
||||
* sampled */
|
||||
uint64_t events[NTHREADS]; /* events bitmap for each thread */
|
||||
};
|
||||
|
||||
struct perf_sample {
|
||||
uint32_t counter;
|
||||
uint32_t timestamp;
|
||||
uint32_t sample_tag;
|
||||
uint32_t duration;
|
||||
};
|
||||
|
||||
struct sample_q {
|
||||
int32_t head, tail;
|
||||
struct perf_sample samples[PERF_SAMPLE_BUFSZ];
|
||||
uint32_t overflows;
|
||||
};
|
||||
|
||||
struct perf_area {
|
||||
struct perf_config_data perf_config;
|
||||
struct sample_q sample_fifo;
|
||||
};
|
||||
|
||||
/*
|
||||
* We have a shared location to keep a global tick counter for all the
|
||||
* CPUS - TODO is this optimal? effect on cache?
|
||||
*/
|
||||
extern uint32_t *xlr_perfmon_timer_loc;
|
||||
|
||||
#define PERFMON_TIMESTAMP_LOC (xlr_perfmon_timer_loc)
|
||||
|
||||
static __inline__ uint32_t
|
||||
perfmon_timestamp_get(void)
|
||||
{
|
||||
return *PERFMON_TIMESTAMP_LOC;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
perfmon_timestamp_set(uint32_t val)
|
||||
{
|
||||
*PERFMON_TIMESTAMP_LOC = val;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
perfmon_timestamp_incr(int val)
|
||||
{
|
||||
(*PERFMON_TIMESTAMP_LOC) += val;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
send_sample_gts(uint32_t tag, uint32_t value, uint32_t td)
|
||||
{
|
||||
xlr_send_sample(tag, value, perfmon_timestamp_get(), td);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple FIFO, one producer - one consumer - circlar queue - no locking
|
||||
*/
|
||||
|
||||
static __inline__ void
|
||||
init_fifo(struct sample_q *q)
|
||||
{
|
||||
q->head = q->tail = 0;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
put_sample(struct sample_q *q, uint32_t sample_tag, uint32_t counter,
|
||||
uint32_t duration)
|
||||
{
|
||||
uint32_t timestamp = perfmon_timestamp_get();
|
||||
int new_tail = (q->tail + 1) % PERF_SAMPLE_BUFSZ;
|
||||
|
||||
if (q->head == new_tail) {
|
||||
q->overflows++;
|
||||
return;
|
||||
}
|
||||
q->samples[new_tail].sample_tag = sample_tag;
|
||||
q->samples[new_tail].counter = counter;
|
||||
q->samples[new_tail].timestamp = timestamp;
|
||||
q->samples[new_tail].duration = duration;
|
||||
|
||||
q->tail = new_tail;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
get_sample(struct sample_q *q, uint32_t * sample_tag, uint32_t * counter,
|
||||
uint32_t * timestamp, uint32_t * duration)
|
||||
{
|
||||
int head = q->head;
|
||||
|
||||
if (head == q->tail)
|
||||
return 0;
|
||||
*sample_tag = q->samples[head].sample_tag;
|
||||
*counter = q->samples[head].counter;
|
||||
*timestamp = q->samples[head].timestamp;
|
||||
*duration = q->samples[head].duration;
|
||||
|
||||
q->head = (head + 1) % PERF_SAMPLE_BUFSZ;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
clear_queue(struct sample_q *q)
|
||||
{
|
||||
q->head = q->tail;
|
||||
}
|
||||
void xlr_perfmon_init_cpu(void *);
|
||||
void xlr_perfmon_sampler(void *);
|
||||
void log_active_core(int core);
|
||||
int get_start_generation(void);
|
||||
|
||||
void xlr_perfmon_clockhandler(void);
|
||||
extern int xlr_perfmon_started;
|
||||
|
||||
#endif /* PERFMON_H */
|
163
sys/mips/rmi/perfmon_kern.c
Normal file
163
sys/mips/rmi/perfmon_kern.c
Normal file
@ -0,0 +1,163 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <machine/smp.h>
|
||||
#include <mips/rmi/perfmon.h>
|
||||
#include <mips/rmi/pic.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <mips/rmi/clock.h>
|
||||
|
||||
|
||||
int xlr_perfmon_started = 0;
|
||||
struct perf_area *xlr_shared_config_area = NULL;
|
||||
uint32_t *xlr_perfmon_timer_loc;
|
||||
uint32_t *xlr_cpu_sampling_interval;
|
||||
uint32_t xlr_perfmon_kernel_version = 1; /* Future use */
|
||||
uint32_t xlr_perfmon_ticks;
|
||||
extern int mips_cpu_online_mask;
|
||||
extern uint32_t cpu_ltop_map[MAXCPU];
|
||||
|
||||
#ifdef SMP
|
||||
static __inline__ void
|
||||
pic_send_perfmon_ipi(int cpu)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
int tid, pid;
|
||||
uint32_t ipi;
|
||||
|
||||
tid = cpu & 0x3;
|
||||
pid = (cpu >> 2) & 0x7;
|
||||
ipi = (pid << 20) | (tid << 16) | IPI_PERFMON;
|
||||
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
xlr_write_reg(mmio, PIC_IPI, ipi);
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
xlr_perfmon_clockhandler(void)
|
||||
{
|
||||
#ifdef SMP
|
||||
int cpu;
|
||||
int i;
|
||||
|
||||
#endif
|
||||
|
||||
if (xlr_perfmon_ticks++ >= (*xlr_cpu_sampling_interval) / (XLR_PIC_HZ / (hz * 1024))) {
|
||||
|
||||
/* update timer */
|
||||
*xlr_perfmon_timer_loc += *xlr_cpu_sampling_interval;
|
||||
xlr_perfmon_ticks = 0;
|
||||
xlr_perfmon_sampler(NULL);
|
||||
#ifdef SMP
|
||||
for (i = 0; i < NCPUS; i = i + NTHREADS) { /* oly thread 0 */
|
||||
cpu = cpu_ltop_map[i];
|
||||
if ((mips_cpu_online_mask & (1 << i)) &&
|
||||
xlr_shared_config_area[cpu / NTHREADS].perf_config.magic ==
|
||||
PERFMON_ACTIVE_MAGIC)
|
||||
pic_send_perfmon_ipi(cpu);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xlr_perfmon_start(void)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
size = (NCORES * sizeof(*xlr_shared_config_area)) +
|
||||
sizeof(*xlr_perfmon_timer_loc) +
|
||||
sizeof(*xlr_cpu_sampling_interval);
|
||||
|
||||
xlr_shared_config_area = malloc(size, M_TEMP, M_WAITOK);
|
||||
if (!xlr_shared_config_area) {
|
||||
/* ERROR */
|
||||
return;
|
||||
}
|
||||
xlr_perfmon_timer_loc = (uint32_t *) (xlr_shared_config_area + NCORES);
|
||||
xlr_cpu_sampling_interval = (uint32_t *) (xlr_perfmon_timer_loc + 1);
|
||||
|
||||
*xlr_cpu_sampling_interval = DEFAULT_CPU_SAMPLING_INTERVAL;
|
||||
*xlr_perfmon_timer_loc = 0;
|
||||
xlr_perfmon_ticks = 0;
|
||||
|
||||
xlr_perfmon_init_cpu(NULL);
|
||||
#ifdef SMP
|
||||
smp_call_function(xlr_perfmon_init_cpu, NULL,
|
||||
PCPU_GET(other_cpus) & 0x11111111);
|
||||
#endif
|
||||
xlr_perfmon_started = 1;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
xlr_perfmon_stop(void)
|
||||
{
|
||||
xlr_perfmon_started = 0;
|
||||
free(xlr_shared_config_area, M_TEMP);
|
||||
xlr_shared_config_area = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_xlr_perfmon_start_stop(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error, val = xlr_perfmon_started;
|
||||
|
||||
error = sysctl_handle_int(oidp, &val, 0, req);
|
||||
if (error != 0 || req->newptr == NULL)
|
||||
return (error);
|
||||
|
||||
if (!xlr_perfmon_started && val != 0)
|
||||
xlr_perfmon_start();
|
||||
else if (xlr_perfmon_started && val == 0)
|
||||
xlr_perfmon_stop();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
SYSCTL_NODE(_debug, OID_AUTO, xlrperf, CTLFLAG_RW, NULL, "XLR PERF Nodes");
|
||||
SYSCTL_PROC(_debug_xlrperf, OID_AUTO, start, CTLTYPE_INT | CTLFLAG_RW,
|
||||
&xlr_perfmon_started, 0, sysctl_xlr_perfmon_start_stop, "I", "set/unset to start/stop "
|
||||
"performance monitoring");
|
342
sys/mips/rmi/perfmon_percpu.c
Normal file
342
sys/mips/rmi/perfmon_percpu.c
Normal file
@ -0,0 +1,342 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <mips/rmi/xlrconfig.h>
|
||||
#include <mips/rmi/perfmon_xlrconfig.h>
|
||||
#include <mips/rmi/perfmon.h>
|
||||
#include <mips/rmi/perfmon_utils.h>
|
||||
#include <mips/rmi/pic.h>
|
||||
#include <mips/rmi/msgring.h>
|
||||
|
||||
#define CC_SAMPLE (PERF_CP2_CREDITS <<24)
|
||||
|
||||
#define CC_REG0 16
|
||||
#define CC_REG1 17
|
||||
#define CC_REG2 18
|
||||
#define CC_REG3 19
|
||||
#define CC_REG4 20
|
||||
#define CC_REG5 21
|
||||
#define CC_REG6 22
|
||||
#define CC_REG7 23
|
||||
#define CC_REG8 24
|
||||
#define CC_REG9 25
|
||||
#define CC_REG10 26
|
||||
#define CC_REG11 27
|
||||
#define CC_REG12 28
|
||||
#define CC_REG13 29
|
||||
#define CC_REG14 30
|
||||
#define CC_REG15 31
|
||||
|
||||
extern uint32_t cpu_ltop_map[MAXCPU];
|
||||
extern struct perf_area *xlr_shared_config_area;
|
||||
|
||||
static __inline__ uint32_t
|
||||
make_cpu_tag(uint32_t val)
|
||||
{
|
||||
return PERF_CP0_COUNTER << 24 | (val & 0xffff);
|
||||
}
|
||||
|
||||
static __inline__ uint32_t
|
||||
make_cp0_perf_control(uint32_t flags, uint32_t thread, uint32_t event)
|
||||
{
|
||||
return (flags & 0x1f) | (thread & 0x03) << 11 | (event & 0x3f) << 5 | 0x01;
|
||||
}
|
||||
|
||||
static __inline__ uint32_t
|
||||
cp0_perf_control_get_thread(uint32_t control_word)
|
||||
{
|
||||
return (control_word & 0x1800) >> 11;
|
||||
}
|
||||
|
||||
static __inline__ uint32_t
|
||||
cp0_perf_control_get_event(uint32_t control_word)
|
||||
{
|
||||
return (control_word & 0x7e0) >> 5;
|
||||
}
|
||||
|
||||
static __inline__ uint32_t
|
||||
read_pic_6_timer_count(void)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
|
||||
/* PIC counts down, convert it to count up */
|
||||
return 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
get_num_events(const uint64_t * events)
|
||||
{
|
||||
int total = 0;
|
||||
int thread;
|
||||
|
||||
for (thread = 0; thread < NTHREADS; thread++) {
|
||||
if (events[thread] == 0)
|
||||
continue;
|
||||
total += get_set_bit_count64(events[thread]);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_first_control_word(uint32_t flags, const uint64_t * events)
|
||||
{
|
||||
int thread, event;
|
||||
|
||||
for (thread = 0; thread < NTHREADS; thread++) {
|
||||
if (events[thread] != 0)
|
||||
break;
|
||||
}
|
||||
if (thread == NTHREADS)
|
||||
return -1;
|
||||
|
||||
event = find_first_set_bit64(events[thread]);
|
||||
return make_cp0_perf_control(flags, thread, event);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_next_control_word(uint32_t current_control_word, const uint64_t * events)
|
||||
{
|
||||
int thread = cp0_perf_control_get_thread(current_control_word);
|
||||
int event = cp0_perf_control_get_event(current_control_word);
|
||||
int i;
|
||||
|
||||
event = find_next_set_bit64(events[thread], event);
|
||||
for (i = 0; event == -1 && i < NTHREADS; i++) {
|
||||
thread = (thread + 1) % NTHREADS;
|
||||
if (events[thread] == 0)
|
||||
continue;
|
||||
event = find_first_set_bit64(events[thread]);
|
||||
}
|
||||
|
||||
ASSERT(event != -1);
|
||||
return make_cp0_perf_control(current_control_word, thread, event);
|
||||
}
|
||||
|
||||
/* Global state per core */
|
||||
#define MY_CORE_NUM (cpu_ltop_map[PCPU_GET(cpuid)]/NTHREADS)
|
||||
#define my_perf_area (&(xlr_shared_config_area[MY_CORE_NUM]))
|
||||
|
||||
static int num_events_array[NCORES];
|
||||
static uint32_t saved_timestamp_array[NCORES];
|
||||
static struct perf_config_data saved_config_array[NCORES];
|
||||
static int cc_sample_array[NCORES];
|
||||
|
||||
#define num_events (num_events_array[MY_CORE_NUM])
|
||||
#define saved_timestamp (saved_timestamp_array[MY_CORE_NUM])
|
||||
#define saved_config (saved_config_array[MY_CORE_NUM])
|
||||
#define cc_sample (cc_sample_array[MY_CORE_NUM])
|
||||
|
||||
static void
|
||||
do_sample_cc_registers(struct sample_q *q, uint32_t mask)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
DPRINT("Sample CC registers %x", mask);
|
||||
msgrng_flags_save(flags);
|
||||
if (mask & 0x00000001)
|
||||
put_sample(q, CC_SAMPLE + 0, read_cc_registers_0123(CC_REG0), 0);
|
||||
if (mask & 0x00000002)
|
||||
put_sample(q, CC_SAMPLE + 1, read_cc_registers_4567(CC_REG0), 0);
|
||||
if (mask & 0x00000004)
|
||||
put_sample(q, CC_SAMPLE + 2, read_cc_registers_0123(CC_REG1), 0);
|
||||
if (mask & 0x00000008)
|
||||
put_sample(q, CC_SAMPLE + 3, read_cc_registers_4567(CC_REG1), 0);
|
||||
if (mask & 0x00000010)
|
||||
put_sample(q, CC_SAMPLE + 4, read_cc_registers_0123(CC_REG2), 0);
|
||||
if (mask & 0x00000020)
|
||||
put_sample(q, CC_SAMPLE + 5, read_cc_registers_4567(CC_REG2), 0);
|
||||
if (mask & 0x00000040)
|
||||
put_sample(q, CC_SAMPLE + 6, read_cc_registers_0123(CC_REG3), 0);
|
||||
if (mask & 0x00000080)
|
||||
put_sample(q, CC_SAMPLE + 7, read_cc_registers_4567(CC_REG3), 0);
|
||||
if (mask & 0x00000100)
|
||||
put_sample(q, CC_SAMPLE + 8, read_cc_registers_0123(CC_REG4), 0);
|
||||
if (mask & 0x00000200)
|
||||
put_sample(q, CC_SAMPLE + 9, read_cc_registers_4567(CC_REG4), 0);
|
||||
if (mask & 0x00000400)
|
||||
put_sample(q, CC_SAMPLE + 10, read_cc_registers_0123(CC_REG5), 0);
|
||||
if (mask & 0x00000800)
|
||||
put_sample(q, CC_SAMPLE + 11, read_cc_registers_4567(CC_REG5), 0);
|
||||
if (mask & 0x00001000)
|
||||
put_sample(q, CC_SAMPLE + 12, read_cc_registers_0123(CC_REG6), 0);
|
||||
if (mask & 0x00002000)
|
||||
put_sample(q, CC_SAMPLE + 13, read_cc_registers_4567(CC_REG6), 0);
|
||||
if (mask & 0x00004000)
|
||||
put_sample(q, CC_SAMPLE + 14, read_cc_registers_0123(CC_REG7), 0);
|
||||
if (mask & 0x00008000)
|
||||
put_sample(q, CC_SAMPLE + 15, read_cc_registers_4567(CC_REG7), 0);
|
||||
if (mask & 0x00010000)
|
||||
put_sample(q, CC_SAMPLE + 16, read_cc_registers_0123(CC_REG8), 0);
|
||||
if (mask & 0x00020000)
|
||||
put_sample(q, CC_SAMPLE + 17, read_cc_registers_4567(CC_REG8), 0);
|
||||
if (mask & 0x00040000)
|
||||
put_sample(q, CC_SAMPLE + 18, read_cc_registers_0123(CC_REG9), 0);
|
||||
if (mask & 0x00080000)
|
||||
put_sample(q, CC_SAMPLE + 19, read_cc_registers_4567(CC_REG9), 0);
|
||||
if (mask & 0x00100000)
|
||||
put_sample(q, CC_SAMPLE + 20, read_cc_registers_0123(CC_REG10), 0);
|
||||
if (mask & 0x00200000)
|
||||
put_sample(q, CC_SAMPLE + 21, read_cc_registers_4567(CC_REG10), 0);
|
||||
if (mask & 0x00400000)
|
||||
put_sample(q, CC_SAMPLE + 22, read_cc_registers_0123(CC_REG11), 0);
|
||||
if (mask & 0x00800000)
|
||||
put_sample(q, CC_SAMPLE + 23, read_cc_registers_4567(CC_REG11), 0);
|
||||
if (mask & 0x01000000)
|
||||
put_sample(q, CC_SAMPLE + 24, read_cc_registers_0123(CC_REG12), 0);
|
||||
if (mask & 0x02000000)
|
||||
put_sample(q, CC_SAMPLE + 24, read_cc_registers_4567(CC_REG12), 0);
|
||||
if (mask & 0x04000000)
|
||||
put_sample(q, CC_SAMPLE + 26, read_cc_registers_0123(CC_REG13), 0);
|
||||
if (mask & 0x08000000)
|
||||
put_sample(q, CC_SAMPLE + 27, read_cc_registers_4567(CC_REG13), 0);
|
||||
if (mask & 0x10000000)
|
||||
put_sample(q, CC_SAMPLE + 28, read_cc_registers_0123(CC_REG14), 0);
|
||||
if (mask & 0x20000000)
|
||||
put_sample(q, CC_SAMPLE + 29, read_cc_registers_4567(CC_REG14), 0);
|
||||
if (mask & 0x40000000)
|
||||
put_sample(q, CC_SAMPLE + 30, read_cc_registers_0123(CC_REG15), 0);
|
||||
if (mask & 0x80000000)
|
||||
put_sample(q, CC_SAMPLE + 31, read_cc_registers_4567(CC_REG15), 0);
|
||||
msgrng_flags_restore(flags);
|
||||
}
|
||||
|
||||
static void
|
||||
reconfigure(void)
|
||||
{
|
||||
uint32_t cntr_cntrl;
|
||||
|
||||
saved_config = my_perf_area->perf_config;
|
||||
num_events = get_num_events(saved_config.events);
|
||||
cc_sample = saved_config.cc_sample_rate;
|
||||
|
||||
DPRINT("%d - reconfigure num_events = %d, events = %llx,%llx,%llx,%llx\n",
|
||||
processor_id(), num_events, saved_config.events[0],
|
||||
saved_config.events[1], saved_config.events[2], saved_config.events[3]);
|
||||
|
||||
if (num_events == 0)
|
||||
return;
|
||||
|
||||
cntr_cntrl = get_first_control_word(saved_config.flags, saved_config.events);
|
||||
write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0, cntr_cntrl);
|
||||
write_c0_register(CP0_PERF_COUNTER, PERFCNTR0, 0); /* reset count */
|
||||
if (num_events > 1) {
|
||||
cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events);
|
||||
write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1, cntr_cntrl);
|
||||
write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */
|
||||
}
|
||||
saved_timestamp = read_pic_6_timer_count();
|
||||
}
|
||||
|
||||
int xlr_perfmon_no_event_count = 0;
|
||||
int xlr_perfmon_sample_count;
|
||||
|
||||
/* timer callback routine */
|
||||
void
|
||||
xlr_perfmon_sampler(void *dummy)
|
||||
{
|
||||
uint32_t current_ts;
|
||||
uint32_t cntr_cntrl = 0;
|
||||
|
||||
/* xlr_ack_interrupt(XLR_PERFMON_IPI_VECTOR); */
|
||||
|
||||
if (my_perf_area->perf_config.magic != PERFMON_ACTIVE_MAGIC)
|
||||
return;
|
||||
/*
|
||||
* If there has been a change in configuation, update the
|
||||
* configuration
|
||||
*/
|
||||
if (saved_config.generation != my_perf_area->perf_config.generation) {
|
||||
reconfigure();
|
||||
return;
|
||||
}
|
||||
/* credit counter samples if reqd */
|
||||
if (saved_config.cc_register_mask && --cc_sample == 0) {
|
||||
cc_sample = saved_config.cc_sample_rate;
|
||||
do_sample_cc_registers(&my_perf_area->sample_fifo,
|
||||
my_perf_area->perf_config.cc_register_mask);
|
||||
}
|
||||
if (num_events == 0) {
|
||||
xlr_perfmon_no_event_count++;
|
||||
return;
|
||||
}
|
||||
/* put samples in the queue */
|
||||
current_ts = read_pic_6_timer_count();
|
||||
cntr_cntrl = read_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0);
|
||||
put_sample(&my_perf_area->sample_fifo, make_cpu_tag(cntr_cntrl),
|
||||
read_c0_register(CP0_PERF_COUNTER, PERFCNTR0), current_ts - saved_timestamp);
|
||||
xlr_perfmon_sample_count++;
|
||||
write_c0_register(CP0_PERF_COUNTER, PERFCNTR0, 0); /* reset count */
|
||||
|
||||
if (num_events > 1) {
|
||||
cntr_cntrl = read_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1);
|
||||
put_sample(&my_perf_area->sample_fifo, make_cpu_tag(cntr_cntrl),
|
||||
read_c0_register(CP0_PERF_COUNTER, PERFCNTR1), current_ts - saved_timestamp);
|
||||
xlr_perfmon_sample_count++;
|
||||
write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */
|
||||
|
||||
if (num_events > 2) {
|
||||
/* multiplex events */
|
||||
cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events);
|
||||
write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0, cntr_cntrl);
|
||||
|
||||
cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events);
|
||||
write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1, cntr_cntrl);
|
||||
}
|
||||
}
|
||||
saved_timestamp = read_pic_6_timer_count();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes time to gather CPU performance counters and credit counters
|
||||
*/
|
||||
void
|
||||
xlr_perfmon_init_cpu(void *dummy)
|
||||
{
|
||||
int processor = cpu_ltop_map[PCPU_GET(cpuid)];
|
||||
|
||||
/* run on just one thread per core */
|
||||
if (processor % 4)
|
||||
return;
|
||||
|
||||
DPRINT("%d : configure with %p", processor, my_perf_area);
|
||||
memset(my_perf_area, 0, sizeof(*my_perf_area));
|
||||
init_fifo(&my_perf_area->sample_fifo);
|
||||
my_perf_area->perf_config.magic = PERFMON_ENABLED_MAGIC;
|
||||
my_perf_area->perf_config.generation = PERFMON_INITIAL_GENERATION;
|
||||
DPRINT("%d : Initialize", processor);
|
||||
|
||||
return;
|
||||
}
|
126
sys/mips/rmi/perfmon_utils.h
Normal file
126
sys/mips/rmi/perfmon_utils.h
Normal file
@ -0,0 +1,126 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <machine/stdarg.h> /* variable args */
|
||||
|
||||
/* TODO optimize of mips, even i & (i-1) is better */
|
||||
|
||||
static int __inline__
|
||||
get_set_bit_count64(uint64_t value)
|
||||
{
|
||||
int i, result = 0;
|
||||
|
||||
for (i = 0; i < sizeof(value) * 8; i++)
|
||||
if (value & (1ULL << i))
|
||||
result++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int __inline__
|
||||
find_first_set_bit64(uint64_t value)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(value) * 8; i++)
|
||||
if (value & (1ULL << i))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __inline__
|
||||
find_next_set_bit64(uint64_t value, int pos)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = pos + 1; i < sizeof(value) * 8; i++)
|
||||
if (value & (1ULL << i))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** --- **/
|
||||
|
||||
static int __inline__
|
||||
get_set_bit_count(uint32_t value)
|
||||
{
|
||||
int i, result = 0;
|
||||
|
||||
for (i = 0; i < sizeof(value) * 8; i++)
|
||||
if (value & (1U << i))
|
||||
result++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int __inline__
|
||||
find_first_set_bit(uint32_t value)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(value) * 8; i++)
|
||||
if (value & (1U << i))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __inline__
|
||||
find_next_set_bit(uint32_t value, int pos)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = pos + 1; i < sizeof(value) * 8; i++)
|
||||
if (value & (1U << i))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void abort();
|
||||
|
||||
#define DPUTC(c) (putchar(c) && fflush(stdout))
|
||||
#define DPRINT(fmt, ...) printf(fmt "\n", __VA_ARGS__)
|
||||
#define ASSERT(x) ((x) || ({ printf("%s failed at (%s:%d)", #x, __FILE__, __LINE__) ; abort(); 0; }) )
|
||||
#else
|
||||
#define DPUTC(c)
|
||||
#define DPRINT(fmt, ...)
|
||||
#define ASSERT(x)
|
||||
#endif
|
||||
|
||||
void xlr_send_sample(uint32_t tag, uint32_t value, uint32_t ts, uint32_t td);
|
||||
|
||||
#endif
|
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/rmi/perfmon_utils.h> /* for DPRINT */
|
||||
|
||||
#define NCPUS 32
|
||||
#define NCORES 8
|
||||
#define NTHREADS 4
|
||||
#define PERF_SAMPLE_BUFSZ 32
|
||||
/*select timeout is 512*1024 microsecs */
|
||||
#define DEFAULT_SYS_SAMPLING_INTERVAL (512*1024)
|
||||
/* default timer value programmed to PIC is 10*1024*1024 */
|
||||
#define DEFAULT_CPU_SAMPLING_INTERVAL (10*1024)
|
||||
#define DEFAULT_CC_SAMPLE_RATE 16
|
||||
#define DEFAULT_CP0_FLAGS 0x0A
|
||||
#define NUM_L2_BANKS 8
|
||||
#define NUM_DRAM_BANKS 4
|
||||
|
||||
/* CP0 register for timestamp */
|
||||
#define CP0_COUNT 9
|
||||
#define CP0_EIRR_REG 9
|
||||
#define CP0_EIRR_SEL 6
|
||||
#define CP0_EIMR_REG 9
|
||||
#define CP0_EIMR_SEL 7
|
||||
|
||||
/* CP0 register for perf counters */
|
||||
#define CP0_PERF_COUNTER 25
|
||||
/* selector values */
|
||||
#define PERFCNTRCTL0 0
|
||||
#define PERFCNTR0 1
|
||||
#define PERFCNTRCTL1 2
|
||||
#define PERFCNTR1 3
|
||||
|
||||
#define XLR_IO_PIC_OFFSET 0x08000
|
||||
#define PIC_SYS_TIMER_0_BASE 0x120
|
||||
#define PIC_SYS_TIMER_NUM_6 6
|
||||
|
||||
/* CP2 registers for reading credit counters */
|
||||
#define CC_REG0 16
|
||||
|
||||
#define read_c0_register(reg, sel) \
|
||||
({ unsigned int __rv; \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set mips32\n\t" \
|
||||
"mfc0\t%0,$%1,%2\n\t" \
|
||||
".set\tpop" \
|
||||
: "=r" (__rv) : "i" (reg), "i" (sel) ); \
|
||||
__rv;})
|
||||
|
||||
#define write_c0_register(reg, sel, value) \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set mips32\n\t" \
|
||||
"mtc0\t%0,$%1,%2\n\t" \
|
||||
".set\tpop" \
|
||||
: : "r" (value), "i" (reg), "i" (sel) );
|
||||
|
||||
#define read_c2_register(reg, sel) \
|
||||
({ unsigned int __rv; \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set mips32\n\t" \
|
||||
"mfc0\t%0,$%1,%2\n\t" \
|
||||
".set\tpop" \
|
||||
: "=r" (__rv) : "i"(reg), "i" (sel) ); \
|
||||
__rv;})
|
||||
|
||||
/*
|
||||
* We have 128 registers in C2 credit counters, reading them one at
|
||||
* a time using bitmap will take a lot of code, so we have two functions
|
||||
* to read registers sel0-3 and sel 4-7 into one 32 bit word.
|
||||
*/
|
||||
|
||||
#define read_cc_registers_0123(reg) \
|
||||
({ \
|
||||
unsigned int __rv; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
".set push\n\t" \
|
||||
".set mips32\n\t" \
|
||||
".set noreorder\n\t" \
|
||||
"mfc2 %0, $%1, 0\n\t" \
|
||||
"mfc2 $8, $%1, 1\n\t" \
|
||||
"sll %0, %0, 8\n\t" \
|
||||
"or %0, %0, $8\n\t" \
|
||||
"mfc2 $8, $%1, 2\n\t" \
|
||||
"sll %0, %0, 8\n\t" \
|
||||
"or %0, %0, $8\n\t" \
|
||||
"mfc2 $8, $%1, 3\n\t" \
|
||||
"sll %0, %0, 8\n\t" \
|
||||
"or %0, %0, $8\n\t" \
|
||||
".set pop" \
|
||||
: "=r" (__rv) : "i"(reg) : "$8"); \
|
||||
\
|
||||
__rv; \
|
||||
})
|
||||
|
||||
#define read_cc_registers_4567(reg) \
|
||||
({ \
|
||||
unsigned int __rv; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
".set push\n\t" \
|
||||
".set mips32\n\t" \
|
||||
".set noreorder\n\t" \
|
||||
"mfc2 %0, $%1, 4\n\t" \
|
||||
"mfc2 $8, $%1, 5\n\t" \
|
||||
"sll %0, %0, 8\n\t" \
|
||||
"or %0, %0, $8\n\t" \
|
||||
"mfc2 $8, $%1, 6\n\t" \
|
||||
"sll %0, %0, 8\n\t" \
|
||||
"or %0, %0, $8\n\t" \
|
||||
"mfc2 $8, $%1, 7\n\t" \
|
||||
"sll %0, %0, 8\n\t" \
|
||||
"or %0, %0, $8\n\t" \
|
||||
".set pop" \
|
||||
: "=r" (__rv) :"i"(reg) : "$8"); \
|
||||
\
|
||||
__rv; \
|
||||
})
|
||||
|
||||
#endif
|
||||
#endif
|
279
sys/mips/rmi/pic.h
Normal file
279
sys/mips/rmi/pic.h
Normal file
@ -0,0 +1,279 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
#ifndef _RMI_PIC_H_
|
||||
#define _RMI_PIC_H_
|
||||
|
||||
extern int rmi_spin_mutex_safe;
|
||||
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <mips/rmi/iomap.h>
|
||||
|
||||
#define PIC_IRT_WD_INDEX 0
|
||||
#define PIC_IRT_TIMER_0_INDEX 1
|
||||
#define PIC_IRT_TIMER_1_INDEX 2
|
||||
#define PIC_IRT_TIMER_2_INDEX 3
|
||||
#define PIC_IRT_TIMER_3_INDEX 4
|
||||
#define PIC_IRT_TIMER_4_INDEX 5
|
||||
#define PIC_IRT_TIMER_5_INDEX 6
|
||||
#define PIC_IRT_TIMER_6_INDEX 7
|
||||
#define PIC_IRT_TIMER_7_INDEX 8
|
||||
#define PIC_IRT_CLOCK_INDEX PIC_IRT_TIMER_7_INDEX
|
||||
#define PIC_IRT_UART_0_INDEX 9
|
||||
#define PIC_IRT_UART_1_INDEX 10
|
||||
#define PIC_IRT_I2C_0_INDEX 11
|
||||
#define PIC_IRT_I2C_1_INDEX 12
|
||||
#define PIC_IRT_PCMCIA_INDEX 13
|
||||
#define PIC_IRT_GPIO_INDEX 14
|
||||
#define PIC_IRT_HYPER_INDEX 15
|
||||
#define PIC_IRT_PCIX_INDEX 16
|
||||
#define PIC_IRT_GMAC0_INDEX 17
|
||||
#define PIC_IRT_GMAC1_INDEX 18
|
||||
#define PIC_IRT_GMAC2_INDEX 19
|
||||
#define PIC_IRT_GMAC3_INDEX 20
|
||||
#define PIC_IRT_XGS0_INDEX 21
|
||||
#define PIC_IRT_XGS1_INDEX 22
|
||||
#define PIC_IRT_HYPER_FATAL_INDEX 23
|
||||
#define PIC_IRT_PCIX_FATAL_INDEX 24
|
||||
#define PIC_IRT_BRIDGE_AERR_INDEX 25
|
||||
#define PIC_IRT_BRIDGE_BERR_INDEX 26
|
||||
#define PIC_IRT_BRIDGE_TB_INDEX 27
|
||||
#define PIC_IRT_BRIDGE_AERR_NMI_INDEX 28
|
||||
|
||||
/* numbering for XLS */
|
||||
#define PIC_IRT_BRIDGE_ERR_INDEX 25
|
||||
#define PIC_IRT_PCIE_LINK0_INDEX 26
|
||||
#define PIC_IRT_PCIE_LINK1_INDEX 27
|
||||
#define PIC_IRT_PCIE_LINK2_INDEX 23
|
||||
#define PIC_IRT_PCIE_LINK3_INDEX 24
|
||||
#define PIC_IRT_PCIE_INT_INDEX 28
|
||||
#define PIC_IRT_PCIE_FATAL_INDEX 29
|
||||
#define PIC_IRT_GPIO_B_INDEX 30
|
||||
#define PIC_IRT_USB_INDEX 31
|
||||
|
||||
#define PIC_NUM_IRTS 32
|
||||
|
||||
#define PIC_SYS_TIMER_MAXVAL_0_BASE 0x100
|
||||
#define PIC_SYS_TIMER_MAXVAL_1_BASE 0x110
|
||||
|
||||
#define PIC_SYS_TIMER_0_BASE 0x120
|
||||
#define PIC_SYS_TIMER_1_BASE 0x130
|
||||
|
||||
#define PIC_CLOCK_TIMER 7
|
||||
|
||||
#define PIC_CTRL 0x00
|
||||
#define PIC_IPI 0x04
|
||||
#define PIC_INT_ACK 0x06
|
||||
|
||||
#define WD_MAX_VAL_0 0x08
|
||||
#define WD_MAX_VAL_1 0x09
|
||||
#define WD_MASK_0 0x0a
|
||||
#define WD_MASK_1 0x0b
|
||||
#define WD_HEARBEAT_0 0x0c
|
||||
#define WD_HEARBEAT_1 0x0d
|
||||
|
||||
#define PIC_IRT_0_BASE 0x40
|
||||
#define PIC_IRT_1_BASE 0x80
|
||||
|
||||
#define PIC_IRT_0_WD (PIC_IRT_0_BASE + PIC_IRT_WD_INDEX)
|
||||
#define PIC_IRT_1_WD (PIC_IRT_1_BASE + PIC_IRT_WD_INDEX)
|
||||
#define PIC_IRT_0_TIMER_0 (PIC_IRT_0_BASE + PIC_IRT_TIMER_0_INDEX)
|
||||
#define PIC_IRT_1_TIMER_0 (PIC_IRT_1_BASE + PIC_IRT_TIMER_0_INDEX)
|
||||
#define PIC_IRT_0_TIMER_1 (PIC_IRT_0_BASE + PIC_IRT_TIMER_1_INDEX)
|
||||
#define PIC_IRT_1_TIMER_1 (PIC_IRT_1_BASE + PIC_IRT_TIMER_1_INDEX)
|
||||
#define PIC_IRT_0_TIMER_2 (PIC_IRT_0_BASE + PIC_IRT_TIMER_2_INDEX)
|
||||
#define PIC_IRT_1_TIMER_2 (PIC_IRT_1_BASE + PIC_IRT_TIMER_2_INDEX)
|
||||
#define PIC_IRT_0_TIMER_3 (PIC_IRT_0_BASE + PIC_IRT_TIMER_3_INDEX)
|
||||
#define PIC_IRT_1_TIMER_3 (PIC_IRT_1_BASE + PIC_IRT_TIMER_3_INDEX)
|
||||
#define PIC_IRT_0_TIMER_4 (PIC_IRT_0_BASE + PIC_IRT_TIMER_4_INDEX)
|
||||
#define PIC_IRT_1_TIMER_4 (PIC_IRT_1_BASE + PIC_IRT_TIMER_4_INDEX)
|
||||
#define PIC_IRT_0_TIMER_5 (PIC_IRT_0_BASE + PIC_IRT_TIMER_5_INDEX)
|
||||
#define PIC_IRT_1_TIMER_5 (PIC_IRT_1_BASE + PIC_IRT_TIMER_5_INDEX)
|
||||
#define PIC_IRT_0_TIMER_6 (PIC_IRT_0_BASE + PIC_IRT_TIMER_6_INDEX)
|
||||
#define PIC_IRT_1_TIMER_6 (PIC_IRT_1_BASE + PIC_IRT_TIMER_6_INDEX)
|
||||
#define PIC_IRT_0_TIMER_7 (PIC_IRT_0_BASE + PIC_IRT_TIMER_7_INDEX)
|
||||
#define PIC_IRT_1_TIMER_7 (PIC_IRT_1_BASE + PIC_IRT_TIMER_7_INDEX)
|
||||
#define PIC_IRT_0_CLOCK (PIC_IRT_0_TIMER_7)
|
||||
#define PIC_IRT_1_CLOCK (PIC_IRT_1_TIMER_7)
|
||||
#define PIC_IRT_0_UART_0 (PIC_IRT_0_BASE + PIC_IRT_UART_0_INDEX)
|
||||
#define PIC_IRT_1_UART_0 (PIC_IRT_1_BASE + PIC_IRT_UART_0_INDEX)
|
||||
#define PIC_IRT_0_UART_1 (PIC_IRT_0_BASE + PIC_IRT_UART_1_INDEX)
|
||||
#define PIC_IRT_1_UART_1 (PIC_IRT_1_BASE + PIC_IRT_UART_1_INDEX)
|
||||
#define PIC_IRT_0_I2C_0 (PIC_IRT_0_BASE + PIC_IRT_I2C_0_INDEX)
|
||||
#define PIC_IRT_1_I2C_0 (PIC_IRT_1_BASE + PIC_IRT_I2C_0_INDEX)
|
||||
#define PIC_IRT_0_I2C_1 (PIC_IRT_0_BASE + PIC_IRT_I2C_1_INDEX)
|
||||
#define PIC_IRT_1_I2C_1 (PIC_IRT_1_BASE + PIC_IRT_I2C_1_INDEX)
|
||||
#define PIC_IRT_0_HYPER (PIC_IRT_0_BASE + PIC_IRT_HYPER_INDEX)
|
||||
#define PIC_IRT_1_HYPER (PIC_IRT_1_BASE + PIC_IRT_HYPER_INDEX)
|
||||
#define PIC_IRT_0_PCIX (PIC_IRT_0_BASE + PIC_IRT_PCIX_INDEX)
|
||||
#define PIC_IRT_1_PCIX (PIC_IRT_1_BASE + PIC_IRT_PCIX_INDEX)
|
||||
|
||||
#define PIC_TIMER_0_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 0)
|
||||
#define PIC_TIMER_0_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 0)
|
||||
#define PIC_TIMER_0_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 0)
|
||||
#define PIC_TIMER_0_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 0)
|
||||
#define PIC_TIMER_6_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 6)
|
||||
#define PIC_TIMER_6_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 6)
|
||||
#define PIC_TIMER_6_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 6)
|
||||
#define PIC_TIMER_6_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 6)
|
||||
#define PIC_TIMER_7_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 7)
|
||||
#define PIC_TIMER_7_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 7)
|
||||
#define PIC_TIMER_7_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 7)
|
||||
#define PIC_TIMER_7_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 7)
|
||||
|
||||
#define PIC_IRQ_BASE 8
|
||||
#define PIC_IRT_FIRST_IRQ PIC_IRQ_BASE
|
||||
#define PIC_WD_IRQ (PIC_IRQ_BASE + PIC_IRT_WD_INDEX)
|
||||
#define PIC_TIMER_0_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_0_INDEX)
|
||||
#define PIC_TIMER_1_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_1_INDEX)
|
||||
#define PIC_TIMER_2_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_2_INDEX)
|
||||
#define PIC_TIMER_3_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_3_INDEX)
|
||||
#define PIC_TIMER_4_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_4_INDEX)
|
||||
#define PIC_TIMER_5_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_5_INDEX)
|
||||
#define PIC_TIMER_6_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_6_INDEX)
|
||||
#define PIC_TIMER_7_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_7_INDEX)
|
||||
#define PIC_CLOCK_IRQ (PIC_TIMER_7_IRQ)
|
||||
#define PIC_UART_0_IRQ (PIC_IRQ_BASE + PIC_IRT_UART_0_INDEX)
|
||||
#define PIC_UART_1_IRQ (PIC_IRQ_BASE + PIC_IRT_UART_1_INDEX)
|
||||
#define PIC_I2C_0_IRQ (PIC_IRQ_BASE + PIC_IRT_I2C_0_INDEX)
|
||||
#define PIC_I2C_1_IRQ (PIC_IRQ_BASE + PIC_IRT_I2C_1_INDEX)
|
||||
#define PIC_PCMCIA_IRQ (PIC_IRQ_BASE + PIC_IRT_PCMCIA_INDEX)
|
||||
#define PIC_GPIO_IRQ (PIC_IRQ_BASE + PIC_IRT_GPIO_INDEX)
|
||||
#define PIC_HYPER_IRQ (PIC_IRQ_BASE + PIC_IRT_HYPER_INDEX)
|
||||
#define PIC_PCIX_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIX_INDEX)
|
||||
#define PIC_GMAC_0_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC0_INDEX)
|
||||
#define PIC_GMAC_1_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC1_INDEX)
|
||||
#define PIC_GMAC_2_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC2_INDEX)
|
||||
#define PIC_GMAC_3_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC3_INDEX)
|
||||
#define PIC_XGS_0_IRQ (PIC_IRQ_BASE + PIC_IRT_XGS0_INDEX)
|
||||
#define PIC_XGS_1_IRQ (PIC_IRQ_BASE + PIC_IRT_XGS1_INDEX)
|
||||
#define PIC_HYPER_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_HYPER_FATAL_INDEX)
|
||||
#define PIC_PCIX_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIX_FATAL_INDEX)
|
||||
#define PIC_BRIDGE_AERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_AERR_INDEX)
|
||||
#define PIC_BRIDGE_BERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_BERR_INDEX)
|
||||
#define PIC_BRIDGE_TB_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_TB_INDEX)
|
||||
#define PIC_BRIDGE_AERR_NMI_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_AERR_NMI_INDEX)
|
||||
|
||||
#define PIC_BRIDGE_ERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_ERR_INDEX)
|
||||
#define PIC_PCIE_LINK0_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK0_INDEX)
|
||||
#define PIC_PCIE_LINK1_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK1_INDEX)
|
||||
#define PIC_PCIE_LINK2_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK2_INDEX)
|
||||
#define PIC_PCIE_LINK3_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK3_INDEX)
|
||||
#define PIC_PCIE_INT_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_INT__INDEX)
|
||||
#define PIC_PCIE_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_FATAL_INDEX)
|
||||
#define PIC_GPIO_B_IRQ (PIC_IRQ_BASE + PIC_IRT_GPIO_B_INDEX)
|
||||
#define PIC_USB_IRQ (PIC_IRQ_BASE + PIC_IRT_USB_INDEX)
|
||||
|
||||
#define PIC_IRT_LAST_IRQ PIC_USB_IRQ
|
||||
|
||||
#define PIC_IRQ_IS_EDGE_TRIGGERED(irq) ( ((irq)>=PIC_TIMER_0_IRQ) && ((irq)<=PIC_TIMER_7_IRQ) )
|
||||
|
||||
#define PIC_IRQ_IS_IRT(irq) ( ((irq)>=PIC_IRT_FIRST_IRQ) && ((irq)<=PIC_IRT_LAST_IRQ) )
|
||||
|
||||
|
||||
extern struct mtx xlr_pic_lock;
|
||||
|
||||
|
||||
static __inline__ __uint32_t
|
||||
pic_read_control(void)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
__uint32_t reg;
|
||||
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
xlr_read_reg(mmio, PIC_CTRL);
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
return reg;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
pic_write_control(__uint32_t control)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
xlr_write_reg(mmio, PIC_CTRL, control);
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
}
|
||||
static __inline__ void
|
||||
pic_update_control(__uint32_t control)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
xlr_write_reg(mmio, PIC_CTRL, (control | xlr_read_reg(mmio, PIC_CTRL)));
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
pic_ack(int irq)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
|
||||
/* ack the pic, if needed */
|
||||
if (!PIC_IRQ_IS_IRT(irq))
|
||||
return;
|
||||
|
||||
if (PIC_IRQ_IS_EDGE_TRIGGERED(irq)) {
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void
|
||||
pic_delayed_ack(int irq)
|
||||
{
|
||||
xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
|
||||
|
||||
if (!PIC_IRQ_IS_IRT(irq))
|
||||
return;
|
||||
|
||||
if (!PIC_IRQ_IS_EDGE_TRIGGERED(irq)) {
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_lock_spin(&xlr_pic_lock);
|
||||
xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
|
||||
if (rmi_spin_mutex_safe)
|
||||
mtx_unlock_spin(&xlr_pic_lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _RMI_PIC_H_ */
|
144
sys/mips/rmi/rmi_mips_exts.h
Normal file
144
sys/mips/rmi/rmi_mips_exts.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
#ifndef __MIPS_EXTS_H__
|
||||
#define __MIPS_EXTS_H__
|
||||
|
||||
#define enable_KX(flags) __asm__ __volatile__ ( \
|
||||
".set push\n" \
|
||||
".set noat\n" \
|
||||
".set noreorder\n" \
|
||||
"mfc0 %0, $12\n\t" \
|
||||
"ori $1, %0, 0x81\n\t" \
|
||||
"xori $1, 1\n\t" \
|
||||
"mtc0 $1, $12\n" \
|
||||
".set pop\n" \
|
||||
: "=r"(flags) )
|
||||
|
||||
#define disable_KX(flags) __asm__ __volatile__ ( \
|
||||
".set push\n" \
|
||||
"mtc0 %0, $12\n" \
|
||||
".set pop\n" \
|
||||
: : "r"(flags) )
|
||||
|
||||
#define CPU_BLOCKID_IFU 0
|
||||
#define CPU_BLOCKID_ICU 1
|
||||
#define CPU_BLOCKID_IEU 2
|
||||
#define CPU_BLOCKID_LSU 3
|
||||
#define CPU_BLOCKID_MMU 4
|
||||
#define CPU_BLOCKID_PRF 5
|
||||
|
||||
#define LSU_CERRLOG_REGID 9
|
||||
|
||||
static __inline__ unsigned int read_32bit_phnx_ctrl_reg(int block, int reg)
|
||||
{
|
||||
unsigned int __res;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set\tpush\n\t"
|
||||
".set\tnoreorder\n\t"
|
||||
"move $9, %1\n"
|
||||
/* "mfcr\t$8, $9\n\t" */
|
||||
".word 0x71280018\n"
|
||||
"move %0, $8\n"
|
||||
".set\tpop"
|
||||
: "=r" (__res) : "r"((block<<8)|reg)
|
||||
: "$8", "$9"
|
||||
);
|
||||
return __res;
|
||||
}
|
||||
|
||||
static __inline__ void write_32bit_phnx_ctrl_reg(int block, int reg, unsigned int value)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
".set\tpush\n\t"
|
||||
".set\tnoreorder\n\t"
|
||||
"move $8, %0\n"
|
||||
"move $9, %1\n"
|
||||
/* "mtcr\t$8, $9\n\t" */
|
||||
".word 0x71280019\n"
|
||||
".set\tpop"
|
||||
:
|
||||
: "r" (value), "r"((block<<8)|reg)
|
||||
: "$8", "$9"
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ unsigned long long read_64bit_phnx_ctrl_reg(int block, int reg)
|
||||
{
|
||||
unsigned int high, low;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set\tmips64\n\t"
|
||||
"move $9, %2\n"
|
||||
/* "mfcr $8, $9\n" */
|
||||
".word 0x71280018\n"
|
||||
"dsrl32 %0, $8, 0\n\t"
|
||||
"dsll32 $8, $8, 0\n\t"
|
||||
"dsrl32 %1, $8, 0\n\t"
|
||||
".set mips0"
|
||||
: "=r" (high), "=r"(low)
|
||||
: "r"((block<<8)|reg)
|
||||
: "$8", "$9"
|
||||
);
|
||||
|
||||
return ( (((unsigned long long)high)<<32) | low);
|
||||
}
|
||||
|
||||
static __inline__ void write_64bit_phnx_ctrl_reg(int block, int reg,unsigned long long value)
|
||||
{
|
||||
__uint32_t low, high;
|
||||
high = value >> 32;
|
||||
low = value & 0xffffffff;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set push\n"
|
||||
".set noreorder\n"
|
||||
".set mips4\n\t"
|
||||
/* Set up "rs" */
|
||||
"move $9, %0\n"
|
||||
|
||||
/* Store 64 bit value in "rt" */
|
||||
"dsll32 $10, %1, 0 \n\t"
|
||||
"dsll32 $8, %2, 0 \n\t"
|
||||
"dsrl32 $8, $8, 0 \n\t"
|
||||
"or $10, $8, $8 \n\t"
|
||||
|
||||
".word 0x71280019\n" /* mtcr $8, $9 */
|
||||
|
||||
".set pop\n"
|
||||
|
||||
: /* No outputs */
|
||||
: "r"((block<<8)|reg), "r" (high), "r" (low)
|
||||
: "$8", "$9", "$10"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
676
sys/mips/rmi/rootfs_list.txt
Normal file
676
sys/mips/rmi/rootfs_list.txt
Normal file
@ -0,0 +1,676 @@
|
||||
# This is the list of files that
|
||||
# should be in your rootfs (copy it from
|
||||
# the build world nfsmount dir. When the rge0
|
||||
# driver gets fixed we should be able to start
|
||||
# using nfs mount... for now we need to use MD_ROOT
|
||||
./.cshrc
|
||||
./.profile
|
||||
./COPYRIGHT
|
||||
./bin
|
||||
./bin/cat
|
||||
./bin/chflags
|
||||
./bin/chio
|
||||
./bin/chmod
|
||||
./bin/cp
|
||||
./bin/csh
|
||||
./bin/tcsh
|
||||
./bin/date
|
||||
./bin/dd
|
||||
./bin/df
|
||||
./bin/domainname
|
||||
./bin/echo
|
||||
./bin/ed
|
||||
./bin/red
|
||||
./bin/expr
|
||||
./bin/getfacl
|
||||
./bin/hostname
|
||||
./bin/kenv
|
||||
./bin/kill
|
||||
./bin/ln
|
||||
./bin/link
|
||||
./bin/ls
|
||||
./bin/mkdir
|
||||
./bin/mv
|
||||
./bin/pax
|
||||
./bin/pkill
|
||||
./bin/pgrep
|
||||
./bin/ps
|
||||
./bin/pwd
|
||||
./bin/rcp
|
||||
./bin/realpath
|
||||
./bin/rm
|
||||
./bin/unlink
|
||||
./bin/rmail
|
||||
./bin/rmdir
|
||||
./bin/setfacl
|
||||
./bin/sh
|
||||
./bin/sleep
|
||||
./bin/stty
|
||||
./bin/sync
|
||||
./bin/test
|
||||
./bin/[
|
||||
./bin/uuidgen
|
||||
./etc
|
||||
./etc/bluetooth
|
||||
./etc/bluetooth/hcsecd.conf
|
||||
./etc/bluetooth/hosts
|
||||
./etc/bluetooth/protocols
|
||||
./etc/defaults
|
||||
./etc/defaults/bluetooth.device.conf
|
||||
./etc/defaults/devfs.rules
|
||||
./etc/defaults/periodic.conf
|
||||
./etc/defaults/rc.conf
|
||||
./etc/devd
|
||||
./etc/devd/asus.conf
|
||||
./etc/gnats
|
||||
./etc/gnats/freefall
|
||||
./etc/gss
|
||||
./etc/gss/mech
|
||||
./etc/gss/qop
|
||||
./etc/mail
|
||||
./etc/mail/mailer.conf
|
||||
./etc/mail/freebsd.mc
|
||||
./etc/mail/freebsd.cf
|
||||
./etc/mail/freebsd.submit.mc
|
||||
./etc/mail/freebsd.submit.cf
|
||||
./etc/mail/helpfile
|
||||
./etc/mail/sendmail.cf
|
||||
./etc/mail/submit.cf
|
||||
./etc/mail/Makefile
|
||||
./etc/mail/README
|
||||
./etc/mail/access.sample
|
||||
./etc/mail/virtusertable.sample
|
||||
./etc/mail/mailertable.sample
|
||||
./etc/mail/aliases
|
||||
./etc/mtree
|
||||
./etc/mtree/BSD.include.dist
|
||||
./etc/mtree/BSD.root.dist
|
||||
./etc/mtree/BSD.usr.dist
|
||||
./etc/mtree/BSD.var.dist
|
||||
./etc/mtree/BSD.sendmail.dist
|
||||
./etc/mtree/BIND.chroot.dist
|
||||
./etc/pam.d
|
||||
./etc/pam.d/README
|
||||
./etc/pam.d/atrun
|
||||
./etc/pam.d/cron
|
||||
./etc/pam.d/ftpd
|
||||
./etc/pam.d/imap
|
||||
./etc/pam.d/kde
|
||||
./etc/pam.d/login
|
||||
./etc/pam.d/other
|
||||
./etc/pam.d/passwd
|
||||
./etc/pam.d/pop3
|
||||
./etc/pam.d/rsh
|
||||
./etc/pam.d/sshd
|
||||
./etc/pam.d/su
|
||||
./etc/pam.d/system
|
||||
./etc/pam.d/telnetd
|
||||
./etc/pam.d/xdm
|
||||
./etc/pam.d/ftp
|
||||
./etc/periodic
|
||||
./etc/periodic/daily
|
||||
./etc/periodic/daily/100.clean-disks
|
||||
./etc/periodic/daily/110.clean-tmps
|
||||
./etc/periodic/daily/120.clean-preserve
|
||||
./etc/periodic/daily/200.backup-passwd
|
||||
./etc/periodic/daily/330.news
|
||||
./etc/periodic/daily/400.status-disks
|
||||
./etc/periodic/daily/404.status-zfs
|
||||
./etc/periodic/daily/405.status-ata-raid
|
||||
./etc/periodic/daily/406.status-gmirror
|
||||
./etc/periodic/daily/407.status-graid3
|
||||
./etc/periodic/daily/408.status-gstripe
|
||||
./etc/periodic/daily/409.status-gconcat
|
||||
./etc/periodic/daily/420.status-network
|
||||
./etc/periodic/daily/450.status-security
|
||||
./etc/periodic/daily/999.local
|
||||
./etc/periodic/daily/310.accounting
|
||||
./etc/periodic/daily/470.status-named
|
||||
./etc/periodic/daily/300.calendar
|
||||
./etc/periodic/daily/130.clean-msgs
|
||||
./etc/periodic/daily/480.status-ntpd
|
||||
./etc/periodic/daily/140.clean-rwho
|
||||
./etc/periodic/daily/430.status-rwho
|
||||
./etc/periodic/daily/150.clean-hoststat
|
||||
./etc/periodic/daily/210.backup-aliases
|
||||
./etc/periodic/daily/440.status-mailq
|
||||
./etc/periodic/daily/460.status-mail-rejects
|
||||
./etc/periodic/daily/500.queuerun
|
||||
./etc/periodic/monthly
|
||||
./etc/periodic/monthly/999.local
|
||||
./etc/periodic/monthly/200.accounting
|
||||
./etc/periodic/security
|
||||
./etc/periodic/security/100.chksetuid
|
||||
./etc/periodic/security/200.chkmounts
|
||||
./etc/periodic/security/300.chkuid0
|
||||
./etc/periodic/security/400.passwdless
|
||||
./etc/periodic/security/410.logincheck
|
||||
./etc/periodic/security/700.kernelmsg
|
||||
./etc/periodic/security/800.loginfail
|
||||
./etc/periodic/security/900.tcpwrap
|
||||
./etc/periodic/security/security.functions
|
||||
./etc/periodic/security/510.ipfdenied
|
||||
./etc/periodic/security/500.ipfwdenied
|
||||
./etc/periodic/security/550.ipfwlimit
|
||||
./etc/periodic/security/520.pfdenied
|
||||
./etc/periodic/weekly
|
||||
./etc/periodic/weekly/340.noid
|
||||
./etc/periodic/weekly/999.local
|
||||
./etc/periodic/weekly/310.locate
|
||||
./etc/periodic/weekly/320.whatis
|
||||
./etc/periodic/weekly/330.catman
|
||||
./etc/periodic/weekly/400.status-pkg
|
||||
./etc/ppp
|
||||
./etc/ppp/ppp.conf
|
||||
./etc/rc.d
|
||||
./etc/rc.d/DAEMON
|
||||
./etc/rc.d/FILESYSTEMS
|
||||
./etc/rc.d/LOGIN
|
||||
./etc/rc.d/NETWORKING
|
||||
./etc/rc.d/SERVERS
|
||||
./etc/rc.d/abi
|
||||
./etc/rc.d/accounting
|
||||
./etc/rc.d/addswap
|
||||
./etc/rc.d/adjkerntz
|
||||
./etc/rc.d/amd
|
||||
./etc/rc.d/apm
|
||||
./etc/rc.d/apmd
|
||||
./etc/rc.d/archdep
|
||||
./etc/rc.d/atm1
|
||||
./etc/rc.d/atm2
|
||||
./etc/rc.d/atm3
|
||||
./etc/rc.d/auditd
|
||||
./etc/rc.d/bgfsck
|
||||
./etc/rc.d/bluetooth
|
||||
./etc/rc.d/bootparams
|
||||
./etc/rc.d/bridge
|
||||
./etc/rc.d/bthidd
|
||||
./etc/rc.d/ccd
|
||||
./etc/rc.d/cleanvar
|
||||
./etc/rc.d/cleartmp
|
||||
./etc/rc.d/cron
|
||||
./etc/rc.d/ddb
|
||||
./etc/rc.d/defaultroute
|
||||
./etc/rc.d/devd
|
||||
./etc/rc.d/devfs
|
||||
./etc/rc.d/dhclient
|
||||
./etc/rc.d/dmesg
|
||||
./etc/rc.d/dumpon
|
||||
./etc/rc.d/encswap
|
||||
./etc/rc.d/faith
|
||||
./etc/rc.d/fsck
|
||||
./etc/rc.d/ftp-proxy
|
||||
./etc/rc.d/ftpd
|
||||
./etc/rc.d/gbde
|
||||
./etc/rc.d/geli
|
||||
./etc/rc.d/geli2
|
||||
./etc/rc.d/gssd
|
||||
./etc/rc.d/hcsecd
|
||||
./etc/rc.d/hostapd
|
||||
./etc/rc.d/hostid
|
||||
./etc/rc.d/hostid_save
|
||||
./etc/rc.d/hostname
|
||||
./etc/rc.d/inetd
|
||||
./etc/rc.d/initrandom
|
||||
./etc/rc.d/ip6addrctl
|
||||
./etc/rc.d/ip6fw
|
||||
./etc/rc.d/ipfilter
|
||||
./etc/rc.d/ipfs
|
||||
./etc/rc.d/ipfw
|
||||
./etc/rc.d/ipmon
|
||||
./etc/rc.d/ipnat
|
||||
./etc/rc.d/ipsec
|
||||
./etc/rc.d/ipxrouted
|
||||
./etc/rc.d/jail
|
||||
./etc/rc.d/kadmind
|
||||
./etc/rc.d/kerberos
|
||||
./etc/rc.d/keyserv
|
||||
./etc/rc.d/kldxref
|
||||
./etc/rc.d/kpasswdd
|
||||
./etc/rc.d/ldconfig
|
||||
./etc/rc.d/local
|
||||
./etc/rc.d/localpkg
|
||||
./etc/rc.d/lockd
|
||||
./etc/rc.d/lpd
|
||||
./etc/rc.d/mixer
|
||||
./etc/rc.d/motd
|
||||
./etc/rc.d/mountcritlocal
|
||||
./etc/rc.d/mountcritremote
|
||||
./etc/rc.d/mountlate
|
||||
./etc/rc.d/mdconfig
|
||||
./etc/rc.d/mdconfig2
|
||||
./etc/rc.d/mountd
|
||||
./etc/rc.d/moused
|
||||
./etc/rc.d/mroute6d
|
||||
./etc/rc.d/mrouted
|
||||
./etc/rc.d/msgs
|
||||
./etc/rc.d/named
|
||||
./etc/rc.d/natd
|
||||
./etc/rc.d/netif
|
||||
./etc/rc.d/netoptions
|
||||
./etc/rc.d/newsyslog
|
||||
./etc/rc.d/pf
|
||||
./etc/rc.d/nfscbd
|
||||
./etc/rc.d/nfsclient
|
||||
./etc/rc.d/nfsd
|
||||
./etc/rc.d/nfsserver
|
||||
./etc/rc.d/nfsuserd
|
||||
./etc/rc.d/nisdomain
|
||||
./etc/rc.d/nsswitch
|
||||
./etc/rc.d/ntpd
|
||||
./etc/rc.d/ntpdate
|
||||
./etc/rc.d/othermta
|
||||
./etc/rc.d/pflog
|
||||
./etc/rc.d/pfsync
|
||||
./etc/rc.d/powerd
|
||||
./etc/rc.d/power_profile
|
||||
./etc/rc.d/ppp
|
||||
./etc/rc.d/pppoed
|
||||
./etc/rc.d/pwcheck
|
||||
./etc/rc.d/quota
|
||||
./etc/rc.d/random
|
||||
./etc/rc.d/rarpd
|
||||
./etc/rc.d/resolv
|
||||
./etc/rc.d/rfcomm_pppd_server
|
||||
./etc/rc.d/root
|
||||
./etc/rc.d/route6d
|
||||
./etc/rc.d/routed
|
||||
./etc/rc.d/routing
|
||||
./etc/rc.d/rpcbind
|
||||
./etc/rc.d/rtadvd
|
||||
./etc/rc.d/rwho
|
||||
./etc/rc.d/savecore
|
||||
./etc/rc.d/sdpd
|
||||
./etc/rc.d/securelevel
|
||||
./etc/rc.d/sendmail
|
||||
./etc/rc.d/serial
|
||||
./etc/rc.d/sppp
|
||||
./etc/rc.d/statd
|
||||
./etc/rc.d/static_arp
|
||||
./etc/rc.d/stf
|
||||
./etc/rc.d/swap1
|
||||
./etc/rc.d/syscons
|
||||
./etc/rc.d/sysctl
|
||||
./etc/rc.d/syslogd
|
||||
./etc/rc.d/timed
|
||||
./etc/rc.d/tmp
|
||||
./etc/rc.d/ugidfw
|
||||
./etc/rc.d/var
|
||||
./etc/rc.d/virecover
|
||||
./etc/rc.d/watchdogd
|
||||
./etc/rc.d/wpa_supplicant
|
||||
./etc/rc.d/ypbind
|
||||
./etc/rc.d/yppasswdd
|
||||
./etc/rc.d/ypserv
|
||||
./etc/rc.d/ypset
|
||||
./etc/rc.d/ypupdated
|
||||
./etc/rc.d/ypxfrd
|
||||
./etc/rc.d/zfs
|
||||
./etc/rc.d/zvol
|
||||
./etc/rc.d/sshd
|
||||
./etc/rc.d/nscd
|
||||
./etc/security
|
||||
./etc/security/audit_class
|
||||
./etc/security/audit_event
|
||||
./etc/security/audit_control
|
||||
./etc/security/audit_user
|
||||
./etc/security/audit_warn
|
||||
./etc/ssh
|
||||
./etc/ssh/ssh_config
|
||||
./etc/ssh/sshd_config
|
||||
./etc/ssh/moduli
|
||||
./etc/ssl
|
||||
./etc/ssl/openssl.cnf
|
||||
./etc/auth.conf
|
||||
./etc/crontab
|
||||
./etc/devd.conf
|
||||
./etc/devfs.conf
|
||||
./etc/ddb.conf
|
||||
./etc/dhclient.conf
|
||||
./etc/disktab
|
||||
./etc/fbtab
|
||||
./etc/ftpusers
|
||||
./etc/gettytab
|
||||
./etc/group
|
||||
./etc/hosts
|
||||
./etc/hosts.allow
|
||||
./etc/hosts.equiv
|
||||
./etc/inetd.conf
|
||||
./etc/libalias.conf
|
||||
./etc/login.access
|
||||
./etc/login.conf
|
||||
./etc/mac.conf
|
||||
./etc/motd
|
||||
./etc/netconfig
|
||||
./etc/network.subr
|
||||
./etc/networks
|
||||
./etc/newsyslog.conf
|
||||
./etc/nsswitch.conf
|
||||
./etc/phones
|
||||
./etc/profile
|
||||
./etc/protocols
|
||||
./etc/rc
|
||||
./etc/rc.bsdextended
|
||||
./etc/rc.firewall
|
||||
./etc/rc.firewall6
|
||||
./etc/rc.initdiskless
|
||||
./etc/rc.sendmail
|
||||
./etc/rc.shutdown
|
||||
./etc/rc.subr
|
||||
./etc/remote
|
||||
./etc/rpc
|
||||
./etc/services
|
||||
./etc/shells
|
||||
./etc/sysctl.conf
|
||||
./etc/syslog.conf
|
||||
./etc/ttys
|
||||
./etc/amd.map
|
||||
./etc/apmd.conf
|
||||
./etc/freebsd-update.conf
|
||||
./etc/locate.rc
|
||||
./etc/hosts.lpd
|
||||
./etc/printcap
|
||||
./etc/mail.rc
|
||||
./etc/manpath.config
|
||||
./etc/ntp.conf
|
||||
./etc/nscd.conf
|
||||
./etc/portsnap.conf
|
||||
./etc/pf.os
|
||||
./etc/csh.cshrc
|
||||
./etc/csh.login
|
||||
./etc/csh.logout
|
||||
./etc/regdomain.xml
|
||||
./etc/login.conf.db
|
||||
./etc/pwd.db
|
||||
./etc/netstart
|
||||
./etc/pccard_ether
|
||||
./etc/rc.suspend
|
||||
./etc/rc.resume
|
||||
./etc/master.passwd
|
||||
./etc/nsmb.conf
|
||||
./etc/opieaccess
|
||||
./etc/spwd.db
|
||||
./etc/passwd
|
||||
./etc/dumpdates
|
||||
./etc/fstab
|
||||
./etc/rc.conf
|
||||
./etc/resolv.conf
|
||||
./etc/termcap
|
||||
./lib
|
||||
./lib/geom
|
||||
./lib/geom/geom_cache.so
|
||||
./lib/geom/geom_concat.so
|
||||
./lib/geom/geom_eli.so
|
||||
./lib/geom/geom_journal.so
|
||||
./lib/geom/geom_label.so
|
||||
./lib/geom/geom_mirror.so
|
||||
./lib/geom/geom_multipath.so
|
||||
./lib/geom/geom_nop.so
|
||||
./lib/geom/geom_part.so
|
||||
./lib/geom/geom_raid3.so
|
||||
./lib/geom/geom_shsec.so
|
||||
./lib/geom/geom_stripe.so
|
||||
./lib/geom/geom_virstor.so
|
||||
./lib/libc.so.7
|
||||
./lib/libcrypt.so.5
|
||||
./lib/libkvm.so.5
|
||||
./lib/libm.so.5
|
||||
./lib/libmd.so.5
|
||||
./lib/libncurses.so.8
|
||||
./lib/libncursesw.so.8
|
||||
./lib/libsbuf.so.5
|
||||
./lib/libutil.so.8
|
||||
./lib/libalias.so.7
|
||||
./lib/libalias_cuseeme.so
|
||||
./lib/libalias_dummy.so
|
||||
./lib/libalias_ftp.so
|
||||
./lib/libalias_irc.so
|
||||
./lib/libalias_nbt.so
|
||||
./lib/libalias_pptp.so
|
||||
./lib/libalias_skinny.so
|
||||
./lib/libalias_smedia.so
|
||||
./lib/libbegemot.so.4
|
||||
./lib/libcam.so.5
|
||||
./lib/libdevstat.so.7
|
||||
./lib/libedit.so.7
|
||||
./lib/libbsdxml.so.4
|
||||
./lib/libgeom.so.5
|
||||
./lib/libipsec.so.4
|
||||
./lib/libipx.so.5
|
||||
./lib/libjail.so.1
|
||||
./lib/libkiconv.so.4
|
||||
./lib/libpcap.so.7
|
||||
./lib/libthr.so.3
|
||||
./lib/libufs.so.5
|
||||
./lib/libz.so.5
|
||||
./lib/libgcc_s.so.1
|
||||
./lib/libreadline.so.8
|
||||
./lib/libssp.so.0
|
||||
./lib/libcrypto.so.6
|
||||
./libexec
|
||||
./libexec/ld-elf.so.1
|
||||
./libexec/ld-elf.so.1.old
|
||||
./sbin
|
||||
./sbin/adjkerntz
|
||||
./sbin/atacontrol
|
||||
./sbin/badsect
|
||||
./sbin/bsdlabel
|
||||
./sbin/camcontrol
|
||||
./sbin/ccdconfig
|
||||
./sbin/clri
|
||||
./sbin/comcontrol
|
||||
./sbin/conscontrol
|
||||
./sbin/devd
|
||||
./sbin/devfs
|
||||
./sbin/dhclient
|
||||
./sbin/dhclient-script
|
||||
./sbin/dmesg
|
||||
./sbin/dump
|
||||
./sbin/rdump
|
||||
./sbin/dumpfs
|
||||
./sbin/dumpon
|
||||
./sbin/fdisk
|
||||
./sbin/ffsinfo
|
||||
./sbin/fsck
|
||||
./sbin/fsck_ffs
|
||||
./sbin/fsck_ufs
|
||||
./sbin/fsck_4.2bsd
|
||||
./sbin/fsdb
|
||||
./sbin/fsirand
|
||||
./sbin/gbde
|
||||
./sbin/fsck_msdosfs
|
||||
./sbin/geom
|
||||
./sbin/gcache
|
||||
./sbin/gconcat
|
||||
./sbin/geli
|
||||
./sbin/gjournal
|
||||
./sbin/glabel
|
||||
./sbin/gmirror
|
||||
./sbin/gmultipath
|
||||
./sbin/gnop
|
||||
./sbin/gpart
|
||||
./sbin/graid3
|
||||
./sbin/gshsec
|
||||
./sbin/gstripe
|
||||
./sbin/gvirstor
|
||||
./sbin/ggatec
|
||||
./sbin/ggated
|
||||
./sbin/ggatel
|
||||
./sbin/growfs
|
||||
./sbin/gvinum
|
||||
./sbin/ifconfig
|
||||
./sbin/init
|
||||
./sbin/ipf
|
||||
./sbin/ipfs
|
||||
./sbin/ipfstat
|
||||
./sbin/ipftest
|
||||
./sbin/ipmon
|
||||
./sbin/ipnat
|
||||
./sbin/ippool
|
||||
./sbin/md5
|
||||
./sbin/ipfw
|
||||
./sbin/ipresend
|
||||
./sbin/iscontrol
|
||||
./sbin/kldconfig
|
||||
./sbin/kldload
|
||||
./sbin/kldstat
|
||||
./sbin/kldunload
|
||||
./sbin/ldconfig
|
||||
./sbin/rmd160
|
||||
./sbin/sha1
|
||||
./sbin/sha256
|
||||
./sbin/mdconfig
|
||||
./sbin/mdmfs
|
||||
./sbin/mount_mfs
|
||||
./sbin/mknod
|
||||
./sbin/mksnap_ffs
|
||||
./sbin/mount
|
||||
./sbin/mount_cd9660
|
||||
./sbin/mount_msdosfs
|
||||
./sbin/mount_nfs
|
||||
./sbin/mount_newnfs
|
||||
./sbin/mount_ntfs
|
||||
./sbin/mount_nullfs
|
||||
./sbin/mount_udf
|
||||
./sbin/mount_unionfs
|
||||
./sbin/natd
|
||||
./sbin/ddb
|
||||
./sbin/newfs
|
||||
./sbin/newfs_msdos
|
||||
./sbin/nfsiod
|
||||
./sbin/nos-tun
|
||||
./sbin/pfctl
|
||||
./sbin/pflogd
|
||||
./sbin/ping
|
||||
./sbin/ping6
|
||||
./sbin/quotacheck
|
||||
./sbin/rcorder
|
||||
./sbin/reboot
|
||||
./sbin/nextboot
|
||||
./sbin/halt
|
||||
./sbin/fastboot
|
||||
./sbin/fasthalt
|
||||
./sbin/recoverdisk
|
||||
./sbin/restore
|
||||
./sbin/rrestore
|
||||
./sbin/route
|
||||
./sbin/routed
|
||||
./sbin/rtquery
|
||||
./sbin/rtsol
|
||||
./sbin/savecore
|
||||
./sbin/setkey
|
||||
./sbin/shutdown
|
||||
./sbin/spppcontrol
|
||||
./sbin/swapon
|
||||
./sbin/swapoff
|
||||
./sbin/swapctl
|
||||
./sbin/sysctl
|
||||
./sbin/tunefs
|
||||
./sbin/umount
|
||||
./sbin/init.bak
|
||||
./var
|
||||
./var/crash
|
||||
./var/crash/minfree
|
||||
./var/db
|
||||
./var/db/locate.database
|
||||
./var/log
|
||||
./var/log/sendmail.st
|
||||
./var/named
|
||||
./var/named/etc
|
||||
./var/named/etc/namedb
|
||||
./var/named/etc/namedb/master
|
||||
./var/named/etc/namedb/master/empty.db
|
||||
./var/named/etc/namedb/master/localhost-forward.db
|
||||
./var/named/etc/namedb/master/localhost-reverse.db
|
||||
./var/named/etc/namedb/named.conf
|
||||
./var/named/etc/namedb/named.root
|
||||
./var/yp
|
||||
./var/yp/Makefile.dist
|
||||
./var/run
|
||||
./var/cron
|
||||
./var/cron/tabs
|
||||
./root
|
||||
./root/.k5login
|
||||
./root/.profile
|
||||
./root/.cshrc
|
||||
./root/.login
|
||||
./list
|
||||
./dev
|
||||
./usr
|
||||
./usr/sbin
|
||||
./usr/sbin/newsyslog
|
||||
./usr/sbin/syslogd
|
||||
./usr/sbin/ip6addrctl
|
||||
./usr/sbin/sendmail
|
||||
./usr/sbin/cron
|
||||
./usr/lib
|
||||
./usr/lib/libpam.so.5
|
||||
./usr/lib/libpam.so
|
||||
./usr/lib/pam_opie.so.5
|
||||
./usr/lib/libbsm.so.3
|
||||
./usr/lib/libbsm.so
|
||||
./usr/lib/pam_chroot.so.5
|
||||
./usr/lib/pam_tacplus.so.5
|
||||
./usr/lib/pam_ssh.so.5
|
||||
./usr/lib/pam_self.so.5
|
||||
./usr/lib/pam_securetty.so.5
|
||||
./usr/lib/pam_rootok.so.5
|
||||
./usr/lib/pam_rhosts.so.5
|
||||
./usr/lib/pam_radius.so.5
|
||||
./usr/lib/pam_permit.so.5
|
||||
./usr/lib/pam_passwdqc.so.5
|
||||
./usr/lib/libcom_err.so.5
|
||||
./usr/lib/libcom_err.so
|
||||
./usr/lib/pam_opieaccess.so.5
|
||||
./usr/lib/pam_nologin.so.5
|
||||
./usr/lib/libc.so.7
|
||||
./usr/lib/pam_login_access.so.5
|
||||
./usr/lib/pam_lastlog.so.5
|
||||
./usr/lib/pam_ksu.so.5
|
||||
./usr/lib/pam_krb5.so.5
|
||||
./usr/lib/pam_guest.so.5
|
||||
./usr/lib/pam_group.so.5
|
||||
./usr/lib/pam_ftpusers.so.5
|
||||
./usr/lib/pam_exec.so.5
|
||||
./usr/lib/pam_echo.so.5
|
||||
./usr/lib/pam_deny.so.5
|
||||
./usr/lib/pam_unix.so.5
|
||||
./usr/lib/pam_chroot.so
|
||||
./usr/lib/libopie.so
|
||||
./usr/lib/pam_deny.so
|
||||
./usr/lib/pam_echo.so
|
||||
./usr/lib/pam_exec.so
|
||||
./usr/lib/pam_ftpusers.so
|
||||
./usr/lib/pam_group.so
|
||||
./usr/lib/pam_guest.so
|
||||
./usr/lib/pam_krb5.so
|
||||
./usr/lib/pam_ksu.so
|
||||
./usr/lib/pam_lastlog.so
|
||||
./usr/lib/pam_login_access.so
|
||||
./usr/lib/pam_nologin.so
|
||||
./usr/lib/pam_opie.so
|
||||
./usr/lib/pam_opieaccess.so
|
||||
./usr/lib/pam_passwdqc.so
|
||||
./usr/lib/pam_permit.so
|
||||
./usr/lib/pam_radius.so
|
||||
./usr/lib/pam_rhosts.so
|
||||
./usr/lib/pam_rootok.so
|
||||
./usr/lib/pam_securetty.so
|
||||
./usr/lib/pam_self.so
|
||||
./usr/lib/pam_ssh.so
|
||||
./usr/lib/pam_tacplus.so
|
||||
./usr/lib/pam_unix.so
|
||||
./usr/lib/libmd.so.5
|
||||
./usr/lib/libbz2.so.4
|
||||
./usr/lib/libgnuregex.so.5
|
||||
./usr/lib/libypclnt.so.4
|
||||
./usr/bin
|
||||
./usr/bin/mktemp
|
||||
./usr/bin/login
|
||||
./usr/bin/uname
|
||||
./usr/bin/awk
|
||||
./usr/bin/logger
|
||||
./usr/bin/grep
|
||||
./usr/bin/ftp
|
||||
./usr/libexec
|
||||
./usr/libexec/getty
|
110
sys/mips/rmi/shared_structs.h
Executable file
110
sys/mips/rmi/shared_structs.h
Executable 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 _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
|
10
sys/mips/rmi/std.xlr
Normal file
10
sys/mips/rmi/std.xlr
Normal file
@ -0,0 +1,10 @@
|
||||
# $FreeBSD$
|
||||
files "../rmi/files.xlr"
|
||||
|
||||
#
|
||||
# XXXMIPS: It's a stub, isn't it?
|
||||
#
|
||||
cpu CPU_MIPS4KC
|
||||
option NOFPU
|
||||
# Kludge for now
|
||||
options TARGET_XLR_XLS
|
113
sys/mips/rmi/tick.c
Normal file
113
sys/mips/rmi/tick.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*-
|
||||
* Copyright (c) 2006-2009 RMI Corporation
|
||||
* Copyright (c) 2006 Bruce M. Simpson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Simple driver for the 32-bit interval counter built in to all
|
||||
* MIPS32 CPUs.
|
||||
* XXX: For calibration this either needs an external clock, or
|
||||
* to be explicitly told what the frequency is.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timetc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/power.h>
|
||||
#include <sys/smp.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/locore.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/hwfunc.h>
|
||||
|
||||
|
||||
struct timecounter counter_timecounter = {
|
||||
platform_get_timecount, /* get_timecount */
|
||||
0, /* no poll_pps */
|
||||
~0u, /* counter_mask */
|
||||
0, /* frequency */
|
||||
"MIPS32", /* name */
|
||||
800, /* quality (adjusted in code) */
|
||||
};
|
||||
|
||||
void tick_init(void);
|
||||
|
||||
|
||||
void
|
||||
tick_init(void)
|
||||
{
|
||||
counter_freq = platform_get_frequency();
|
||||
if (bootverbose)
|
||||
printf("MIPS32 clock: %u MHz", cpu_clock);
|
||||
|
||||
counter_timecounter.tc_frequency = counter_freq;
|
||||
tc_init(&counter_timecounter);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sysctl_machdep_counter_freq(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error;
|
||||
uint64_t freq;
|
||||
|
||||
/*
|
||||
* RRS wonders if this will really work. You don't change the req of
|
||||
* the system here, it would require changes to the RMI PIC in order
|
||||
* to get the TC to run at a differrent frequency.
|
||||
*/
|
||||
|
||||
if (counter_timecounter.tc_frequency == 0)
|
||||
return (EOPNOTSUPP);
|
||||
freq = counter_freq;
|
||||
error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
|
||||
if (error == 0 && req->newptr != NULL) {
|
||||
counter_freq = freq;
|
||||
counter_timecounter.tc_frequency = counter_freq;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
SYSCTL_PROC(_machdep, OID_AUTO, counter_freq, CTLTYPE_QUAD | CTLFLAG_RW,
|
||||
0, sizeof(u_int), sysctl_machdep_counter_freq, "IU", "");
|
80
sys/mips/rmi/uart_bus_xlr_iodi.c
Normal file
80
sys/mips/rmi/uart_bus_xlr_iodi.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Raza Microelectronics
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/uart/uart_bus_iodi.c,v 1.6.2.5 2006/02/15 09:16:01 marius Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <sys/rman.h>
|
||||
#include <machine/resource.h>
|
||||
#include <mips/rmi/iomap.h>
|
||||
#include <dev/uart/uart.h>
|
||||
#include <dev/uart/uart_bus.h>
|
||||
#include <dev/uart/uart_cpu.h>
|
||||
|
||||
static int uart_iodi_probe(device_t dev);
|
||||
|
||||
static device_method_t uart_iodi_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, uart_iodi_probe),
|
||||
DEVMETHOD(device_attach, uart_bus_attach),
|
||||
DEVMETHOD(device_detach, uart_bus_detach),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static driver_t uart_iodi_driver = {
|
||||
uart_driver_name,
|
||||
uart_iodi_methods,
|
||||
sizeof(struct uart_softc),
|
||||
};
|
||||
|
||||
|
||||
extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
|
||||
static int
|
||||
uart_iodi_probe(device_t dev)
|
||||
{
|
||||
struct uart_softc *sc;
|
||||
sc = device_get_softc(dev);
|
||||
sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
|
||||
sc->sc_class = &uart_ns8250_class;
|
||||
bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
|
||||
sc->sc_sysdev->bas.bst = rmi_bus_space;
|
||||
sc->sc_sysdev->bas.bsh = MIPS_PHYS_TO_KSEG1(XLR_UART0ADDR);
|
||||
sc->sc_bas.bst = rmi_bus_space;
|
||||
sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(XLR_UART0ADDR);
|
||||
/* regshft = 2, rclk = 66000000, rid = 0, chan = 0 */
|
||||
return (uart_bus_probe(dev, 2, 66000000, 0, 0));
|
||||
}
|
||||
|
||||
DRIVER_MODULE(uart, iodi, uart_iodi_driver, uart_devclass, 0, 0);
|
84
sys/mips/rmi/uart_cpu_mips_xlr.c
Normal file
84
sys/mips/rmi/uart_cpu_mips_xlr.c
Normal file
@ -0,0 +1,84 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: uart_cpu_mips_xlr.c,v 1.5 2008-07-16 20:22:39 jayachandranc Exp $
|
||||
*/
|
||||
/*
|
||||
* Skeleton of this file was based on respective code for ARM
|
||||
* code written by Olivier Houchard.
|
||||
*/
|
||||
/*
|
||||
* XLRMIPS: This file is hacked from arm/...
|
||||
*/
|
||||
#include "opt_uart.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cons.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/uart/uart.h>
|
||||
#include <dev/uart/uart_cpu.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <mips/rmi/iomap.h>
|
||||
|
||||
bus_space_tag_t uart_bus_space_io;
|
||||
bus_space_tag_t uart_bus_space_mem;
|
||||
|
||||
int
|
||||
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
|
||||
{
|
||||
return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
|
||||
{
|
||||
di->ops = uart_getops(&uart_ns8250_class);
|
||||
di->bas.chan = 0;
|
||||
di->bas.bst = rmi_bus_space;
|
||||
di->bas.bsh = MIPS_PHYS_TO_KSEG1(XLR_UART0ADDR);
|
||||
|
||||
di->bas.regshft = 2;
|
||||
/* divisor = rclk / (baudrate * 16); */
|
||||
di->bas.rclk = 66000000;
|
||||
di->baudrate = 0;
|
||||
di->databits = 8;
|
||||
di->stopbits = 1;
|
||||
di->parity = UART_PARITY_NONE;
|
||||
|
||||
uart_bus_space_io = NULL;
|
||||
uart_bus_space_mem = rmi_bus_space;
|
||||
return (0);
|
||||
}
|
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/rmi/xlrconfig.h>
|
||||
#include <mips/rmi/shared_structs.h>
|
||||
#include <mips/rmi/shared_structs_func.h>
|
||||
|
||||
#include <ddb/ddb.h>
|
||||
|
||||
#if 0
|
||||
static cn_probe_t xlr_boot1_cnprobe;
|
||||
static cn_init_t xlr_boot1_cninit;
|
||||
static cn_term_t xlr_boot1_cnterm;
|
||||
static cn_getc_t xlr_boot1_cngetc;
|
||||
static cn_checkc_t xlr_boot1_cncheckc;
|
||||
static cn_putc_t xlr_boot1_cnputc;
|
||||
|
||||
CONS_DRIVER(xlrboot, xlr_boot1_cnprobe, xlr_boot1_cninit, xlr_boot1_cnterm, xlr_boot1_cngetc,
|
||||
xlr_boot1_cncheckc, xlr_boot1_cnputc, NULL);
|
||||
|
||||
/*
|
||||
* Device gets probed. Firmwire should be checked here probably.
|
||||
*/
|
||||
static void
|
||||
xlr_boot1_cnprobe(struct consdev *cp)
|
||||
{
|
||||
cp->cn_pri = CN_NORMAL;
|
||||
cp->cn_tp = NULL;
|
||||
cp->cn_arg = NULL; /* softc */
|
||||
cp->cn_unit = -1; /* ? */
|
||||
cp->cn_flags = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization.
|
||||
*/
|
||||
static void
|
||||
xlr_boot1_cninit(struct consdev *cp)
|
||||
{
|
||||
sprintf(cp->cn_name, "boot1");
|
||||
}
|
||||
|
||||
static void
|
||||
xlr_boot1_cnterm(struct consdev *cp)
|
||||
{
|
||||
cp->cn_pri = CN_DEAD;
|
||||
cp->cn_flags = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
xlr_boot1_cngetc(struct consdev *cp)
|
||||
{
|
||||
return boot1_info_uart_getchar_func(&xlr_boot1_info);
|
||||
}
|
||||
|
||||
static void
|
||||
xlr_boot1_cnputc(struct consdev *cp, int c)
|
||||
{
|
||||
boot1_info_uart_putchar_func(&xlr_boot1_info, c);
|
||||
}
|
||||
|
||||
static int
|
||||
xlr_boot1_cncheckc(struct consdev *cp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
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)
|
455
sys/mips/rmi/xlr_i2c.c
Normal file
455
sys/mips/rmi/xlr_i2c.c
Normal file
@ -0,0 +1,455 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/mips/xlr/xlr_i2c.c,v 1.20.8.1 2008/08/25 23:17:51 cognet Exp $");
|
||||
|
||||
/*
|
||||
* I2C driver for the Palm-BK3220 I2C Host adapter on the RMI XLR.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
|
||||
#include <mips/rmi/iomap.h>
|
||||
#include <mips/include/resource.h>
|
||||
|
||||
#include "iicbus_if.h"
|
||||
|
||||
#define DEVTOIICBUS(dev) ((struct iicbus_device*)device_get_ivars(dev))
|
||||
|
||||
#define I2C_PALM_CFG 0x00
|
||||
#define I2C_PALM_CLKDIV 0x01
|
||||
#define I2C_PALM_DEVADDR 0x02
|
||||
#define I2C_PALM_ADDR 0x03
|
||||
#define I2C_PALM_DATAOUT 0x04
|
||||
#define I2C_PALM_DATAIN 0x05
|
||||
#define I2C_PALM_STATUS 0x06
|
||||
#define I2C_PALM_STARTXFR 0x07
|
||||
#define I2C_PALM_BYTECNT 0x08
|
||||
#define I2C_PALM_HDSTATIM 0x09
|
||||
|
||||
/* TEST Values!! Change as required */
|
||||
#define I2C_PALM_CFG_DEF 0x000000F8 /* 8-Bit Addr + POR Values */
|
||||
#define I2C_PALM_CLKDIV_DEF 0x14A //0x00000052
|
||||
#define I2C_PALM_HDSTATIM_DEF 0x107 //0x00000000
|
||||
|
||||
#define I2C_PALM_STARTXFR_RD 0x00000001
|
||||
#define I2C_PALM_STARTXFR_WR 0x00000000
|
||||
|
||||
|
||||
#define PHOENIX_IO_I2C_0_OFFSET 0x16000
|
||||
#define PHOENIX_IO_I2C_1_OFFSET 0x17000
|
||||
|
||||
#define ARIZONA_I2c_BUS 1
|
||||
|
||||
int bus = 1;
|
||||
|
||||
|
||||
uint8_t current_slave;
|
||||
uint8_t read_address;
|
||||
static xlr_reg_t *iobase_i2c_regs;
|
||||
|
||||
static devclass_t xlr_i2c_devclass;
|
||||
|
||||
/*
|
||||
* Device methods
|
||||
*/
|
||||
static int xlr_i2c_probe(device_t);
|
||||
static int xlr_i2c_attach(device_t);
|
||||
static int xlr_i2c_detach(device_t);
|
||||
|
||||
static int xlr_i2c_start(device_t dev, u_char slave, int timeout);
|
||||
static int xlr_i2c_stop(device_t dev);
|
||||
static int xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay);
|
||||
static int xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout);
|
||||
|
||||
|
||||
struct xlr_i2c_softc {
|
||||
device_t dev; /* Myself */
|
||||
struct resource *mem_res; /* Memory resource */
|
||||
volatile int flags;
|
||||
#define RXRDY 4
|
||||
#define TXRDY 0x10
|
||||
int sc_started;
|
||||
int twi_addr;
|
||||
device_t iicbus;
|
||||
};
|
||||
|
||||
|
||||
#define MDELAY(a){ \
|
||||
unsigned long local_loop = 0xfffff; \
|
||||
while(local_loop--); \
|
||||
}\
|
||||
|
||||
static void
|
||||
get_i2c_base(void)
|
||||
{
|
||||
if (bus == 0)
|
||||
iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_0_OFFSET);
|
||||
else
|
||||
iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_1_OFFSET);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
palm_write(int reg, int value)
|
||||
{
|
||||
get_i2c_base();
|
||||
xlr_write_reg(iobase_i2c_regs, reg, value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
palm_read(int reg)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
get_i2c_base();
|
||||
val = xlr_read_reg(iobase_i2c_regs, reg);
|
||||
return ((int)val);
|
||||
}
|
||||
|
||||
static int
|
||||
palm_addr_only(uint8_t addr, uint8_t offset)
|
||||
{
|
||||
volatile uint32_t regVal = 0x00;
|
||||
|
||||
palm_write(I2C_PALM_ADDR, offset);
|
||||
palm_write(I2C_PALM_DEVADDR, addr);
|
||||
palm_write(I2C_PALM_CFG, 0xfa);
|
||||
palm_write(I2C_PALM_STARTXFR, 0x02);
|
||||
regVal = palm_read(I2C_PALM_STATUS);
|
||||
if (regVal & 0x0008) {
|
||||
printf("palm_addr_only: ACKERR. Aborting...\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
palm_rx(uint8_t addr, uint8_t offset, uint8_t len,
|
||||
uint8_t * buf)
|
||||
{
|
||||
volatile uint32_t regVal = 0x00, ctr = 0x00;
|
||||
int timeOut, numBytes = 0x00;
|
||||
|
||||
palm_write(I2C_PALM_CFG, 0xfa);
|
||||
palm_write(I2C_PALM_BYTECNT, len);
|
||||
palm_write(I2C_PALM_DEVADDR, addr);
|
||||
//DEVADDR = 0x4c, 0x68
|
||||
MDELAY(1);
|
||||
|
||||
for (numBytes = 0x00; numBytes < len; numBytes++) {
|
||||
palm_write(I2C_PALM_ADDR, offset + numBytes);
|
||||
//I2C_PALM_ADDR:offset
|
||||
MDELAY(1);
|
||||
if (!ctr) {
|
||||
/* Trigger a READ Transaction */
|
||||
palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD);
|
||||
ctr++;
|
||||
}
|
||||
/* Error Conditions [Begin] */
|
||||
regVal = palm_read(I2C_PALM_STATUS);
|
||||
MDELAY(1);
|
||||
if (regVal & 0x0008) {
|
||||
printf("palm_rx: ACKERR. Aborting...\n");
|
||||
return -1;
|
||||
}
|
||||
timeOut = 10;
|
||||
while ((regVal & 0x0030) && timeOut--) {
|
||||
palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD);
|
||||
regVal = palm_read(I2C_PALM_STATUS);
|
||||
}
|
||||
if (timeOut == 0x00) {
|
||||
printf("palm_rx: TimedOut on Valid STARTXFR/Arbitration\n");
|
||||
return -1;
|
||||
}
|
||||
timeOut = 10;
|
||||
/* Do we have valid data from the device yet..? */
|
||||
regVal &= 0x0004;
|
||||
while (!regVal && timeOut--) {
|
||||
regVal = palm_read(I2C_PALM_STATUS) & 0x0004;
|
||||
}
|
||||
if (timeOut == 0x00) {
|
||||
printf("palm_rx: TimedOut Waiting for Valid Data\n");
|
||||
return -1;
|
||||
}
|
||||
/* Error Conditions [End] */
|
||||
/* Read the data */
|
||||
buf[numBytes] = (uint8_t) palm_read(I2C_PALM_DATAIN);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
wait_for_idle(void)
|
||||
{
|
||||
int timeOut = 0x1000;
|
||||
volatile uint32_t regVal = 0x00;
|
||||
|
||||
regVal = palm_read(I2C_PALM_STATUS) & 0x0001;
|
||||
while (regVal && timeOut--) {
|
||||
regVal = palm_read(I2C_PALM_STATUS) & 0x0001;
|
||||
}
|
||||
if (timeOut == 0x00)
|
||||
return -1; /* Timed Out */
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
palm_tx(uint8_t addr, uint8_t offset, uint8_t * buf, uint8_t len)
|
||||
{
|
||||
volatile uint32_t regVal = 0x00;
|
||||
int timeOut, ctr = 0x00, numBytes = len;
|
||||
|
||||
for (ctr = 0x00; ctr < len; ctr++) {
|
||||
if (wait_for_idle() < 0) {
|
||||
printf("TimedOut on Waiting for I2C Bus Idle.\n");
|
||||
return -EIO;
|
||||
}
|
||||
palm_write(I2C_PALM_CFG, 0xF8);
|
||||
palm_write(I2C_PALM_BYTECNT, 0x00);
|
||||
palm_write(I2C_PALM_DEVADDR, addr);
|
||||
//0x4c, 0x68
|
||||
palm_write(I2C_PALM_ADDR, offset + numBytes - 1);
|
||||
//offset
|
||||
palm_write(I2C_PALM_DATAOUT, buf[ctr]);
|
||||
palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_WR);
|
||||
MDELAY(1);
|
||||
|
||||
regVal = palm_read(I2C_PALM_STATUS);
|
||||
MDELAY(1);
|
||||
if (regVal & 0x0008) {
|
||||
printf("palm_tx: ACKERR. Aborting...\n");
|
||||
return -1;
|
||||
}
|
||||
timeOut = 0x1000;
|
||||
while (!(regVal & 0x0002) && timeOut) {
|
||||
regVal = palm_read(I2C_PALM_STATUS);
|
||||
timeOut--;
|
||||
}
|
||||
if (timeOut == 0x00) {
|
||||
printf("palm_tx: [TimeOut] SDOEMPTY Not Set\n");
|
||||
return -1;
|
||||
}
|
||||
timeOut = 1000;
|
||||
while ((regVal & 0x0030) && timeOut) {
|
||||
palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_WR);
|
||||
regVal = palm_read(I2C_PALM_STATUS);
|
||||
timeOut--;
|
||||
}
|
||||
if (timeOut == 0x00) {
|
||||
printf("palm_rx: TimedOut on Valid STARTXFR/Arbitration\n");
|
||||
return -1;
|
||||
}
|
||||
numBytes--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
xlr_i2c_probe(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "I2C bus controller");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We add all the devices which we know about.
|
||||
* The generic attach routine will attach them if they are alive.
|
||||
*/
|
||||
static int
|
||||
xlr_i2c_attach(device_t dev)
|
||||
{
|
||||
struct xlr_i2c_softc *sc;
|
||||
int rid;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
|
||||
RF_ACTIVE);
|
||||
if (sc->mem_res == NULL) {
|
||||
printf("not able to allocate the bus resource\n");
|
||||
}
|
||||
if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL)
|
||||
printf("could not allocate iicbus instance\n");
|
||||
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
xlr_i2c_detach(device_t dev)
|
||||
{
|
||||
bus_generic_detach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
static int
|
||||
xlr_i2c_add_child(device_t dev, int order, const char *name, int unit)
|
||||
{
|
||||
printf("********* %s ******** \n", __FUNCTION__);
|
||||
device_add_child_ordered(dev, order, name, unit);
|
||||
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
*/
|
||||
|
||||
static int
|
||||
xlr_i2c_start(device_t dev, u_char slave, int timeout)
|
||||
{
|
||||
int error = 0;
|
||||
struct xlr_i2c_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->sc_started = 1;
|
||||
|
||||
current_slave = (slave >> 1);
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
xlr_i2c_stop(device_t dev)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last,
|
||||
int delay)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (palm_addr_only(current_slave, read_address) == -1) {
|
||||
printf("I2C ADDRONLY Phase Fail.\n");
|
||||
return -1;
|
||||
}
|
||||
if (palm_rx(current_slave, read_address, len, buf) == -1) {
|
||||
printf("I2C Read Fail.\n");
|
||||
return -1;
|
||||
}
|
||||
*read = len;
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout /* us */ )
|
||||
{
|
||||
|
||||
int error = 0;
|
||||
uint8_t write_address;
|
||||
|
||||
if (len == 1) {
|
||||
/* address for the next read */
|
||||
read_address = buf[0];
|
||||
return error;
|
||||
}
|
||||
if (len < 2)
|
||||
return (-1);
|
||||
|
||||
write_address = buf[0];
|
||||
|
||||
/*
|
||||
* for write operation, buf[0] contains the register offset and
|
||||
* buf[1] onwards contains the value
|
||||
*/
|
||||
palm_tx(current_slave, write_address, &buf[1], len - 1);
|
||||
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
xlr_i2c_callback(device_t dev, int index, caddr_t *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xlr_i2c_repeated_start(device_t dev, u_char slave, int timeout)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static device_method_t xlr_i2c_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, xlr_i2c_probe),
|
||||
DEVMETHOD(device_attach, xlr_i2c_attach),
|
||||
DEVMETHOD(device_detach, xlr_i2c_detach),
|
||||
|
||||
/* iicbus interface */
|
||||
DEVMETHOD(iicbus_callback, xlr_i2c_callback),
|
||||
DEVMETHOD(iicbus_repeated_start, xlr_i2c_repeated_start),
|
||||
DEVMETHOD(iicbus_start, xlr_i2c_start),
|
||||
DEVMETHOD(iicbus_stop, xlr_i2c_stop),
|
||||
DEVMETHOD(iicbus_write, xlr_i2c_write),
|
||||
DEVMETHOD(iicbus_read, xlr_i2c_read),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static driver_t xlr_i2c_driver = {
|
||||
"xlr_i2c",
|
||||
xlr_i2c_methods,
|
||||
sizeof(struct xlr_i2c_softc),
|
||||
};
|
||||
|
||||
DRIVER_MODULE(xlr_i2c, iodi, xlr_i2c_driver, xlr_i2c_devclass, 0, 0);
|
726
sys/mips/rmi/xlr_machdep.c
Normal file
726
sys/mips/rmi/xlr_machdep.c
Normal file
@ -0,0 +1,726 @@
|
||||
/*-
|
||||
* Copyright (c) 2006-2009 RMI Corporation
|
||||
* Copyright (c) 2002-2004 Juli Mallett <jmallett@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/rtprio.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/interrupt.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/sched.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#include <sys/cons.h> /* cinit() */
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/timetc.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_page.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/cpuinfo.h>
|
||||
#include <machine/cpuregs.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/hwfunc.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/asm.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/trap.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/fls64.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <machine/smp.h>
|
||||
#include <mips/rmi/rmi_mips_exts.h>
|
||||
|
||||
#include <mips/rmi/iomap.h>
|
||||
#include <mips/rmi/clock.h>
|
||||
#include <mips/rmi/msgring.h>
|
||||
#include <mips/rmi/xlrconfig.h>
|
||||
#include <mips/rmi/interrupt.h>
|
||||
#include <mips/rmi/pic.h>
|
||||
|
||||
#ifdef XLR_PERFMON
|
||||
#include <mips/rmi/perfmon.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void platform_prep_smp_launch(void);
|
||||
|
||||
unsigned long xlr_io_base = (unsigned long)(DEFAULT_XLR_IO_BASE);
|
||||
|
||||
/* 4KB static data aread to keep a copy of the bootload env until
|
||||
the dynamic kenv is setup */
|
||||
char boot1_env[4096];
|
||||
extern unsigned long _gp;
|
||||
int rmi_spin_mutex_safe=0;
|
||||
/*
|
||||
* Parameters from boot loader
|
||||
*/
|
||||
struct boot1_info xlr_boot1_info;
|
||||
struct xlr_loader_info xlr_loader_info; /* FIXME : Unused */
|
||||
int xlr_run_mode;
|
||||
int xlr_argc;
|
||||
char **xlr_argv, **xlr_envp;
|
||||
uint64_t cpu_mask_info;
|
||||
uint32_t xlr_online_cpumask;
|
||||
|
||||
#ifdef SMP
|
||||
static unsigned long xlr_secondary_gp[MAXCPU];
|
||||
static unsigned long xlr_secondary_sp[MAXCPU];
|
||||
|
||||
#endif
|
||||
extern int mips_cpu_online_mask;
|
||||
extern int mips_cpu_logical_mask;
|
||||
uint32_t cpu_ltop_map[MAXCPU];
|
||||
uint32_t cpu_ptol_map[MAXCPU];
|
||||
uint32_t xlr_core_cpu_mask = 0x1; /* Core 0 thread 0 is always there */
|
||||
|
||||
void
|
||||
platform_reset(void)
|
||||
{
|
||||
/* FIXME : use proper define */
|
||||
u_int32_t *mmio = (u_int32_t *) 0xbef18000;
|
||||
|
||||
printf("Rebooting the system now\n");
|
||||
mmio[8] = 0x1;
|
||||
}
|
||||
|
||||
void
|
||||
platform_secondary_init(void)
|
||||
{
|
||||
#ifdef SMP
|
||||
xlr_msgring_cpu_init();
|
||||
|
||||
/* Setup interrupts for secondary CPUs here */
|
||||
mips_mask_hard_irq(IPI_SMP_CALL_FUNCTION);
|
||||
mips_mask_hard_irq(IPI_STOP);
|
||||
mips_mask_hard_irq(IPI_RENDEZVOUS);
|
||||
mips_mask_hard_irq(IPI_AST);
|
||||
mips_mask_hard_irq(IRQ_TIMER);
|
||||
#ifdef XLR_PERFMON
|
||||
mips_mask_hard_irq(IPI_PERFMON);
|
||||
#endif
|
||||
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int xlr_asid_pcpu = 256; /* This the default */
|
||||
int xlr_shtlb_enabled = 0;
|
||||
|
||||
/* This function sets up the number of tlb entries available
|
||||
to the kernel based on the number of threads brought up.
|
||||
The ASID range also gets divided similarly.
|
||||
THE NUMBER OF THREADS BROUGHT UP IN EACH CORE MUST BE THE SAME
|
||||
NOTE: This function will mark all 64TLB entries as available
|
||||
to the threads brought up in the core. If kernel is brought with say mask
|
||||
0x33333333, no TLBs will be available to the threads in each core.
|
||||
*/
|
||||
static void
|
||||
setup_tlb_resource(void)
|
||||
{
|
||||
int mmu_setup;
|
||||
int value = 0;
|
||||
uint32_t cpu_map = xlr_boot1_info.cpu_online_map;
|
||||
uint32_t thr_mask = cpu_map >> (xlr_cpu_id() << 2);
|
||||
uint8_t core0 = xlr_boot1_info.cpu_online_map & 0xf;
|
||||
uint8_t core_thr_mask;
|
||||
int i = 0, count = 0;
|
||||
|
||||
/* If CPU0 did not enable shared TLB, other cores need to follow */
|
||||
if ((xlr_cpu_id() != 0) && (xlr_shtlb_enabled == 0))
|
||||
return;
|
||||
/* First check if each core is brought up with the same mask */
|
||||
for (i = 1; i < 8; i++) {
|
||||
core_thr_mask = cpu_map >> (i << 2);
|
||||
core_thr_mask &= 0xf;
|
||||
if (core_thr_mask && core_thr_mask != core0) {
|
||||
printf
|
||||
("Each core must be brought with same cpu mask\n");
|
||||
printf("Cannot enabled shared TLB. ");
|
||||
printf("Falling back to split TLB mode\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xlr_shtlb_enabled = 1;
|
||||
for (i = 0; i < 4; i++)
|
||||
if (thr_mask & (1 << i))
|
||||
count++;
|
||||
switch (count) {
|
||||
case 1:
|
||||
xlr_asid_pcpu = 256;
|
||||
break;
|
||||
case 2:
|
||||
xlr_asid_pcpu = 128;
|
||||
value = 0x2;
|
||||
break;
|
||||
default:
|
||||
xlr_asid_pcpu = 64;
|
||||
value = 0x3;
|
||||
break;
|
||||
}
|
||||
|
||||
mmu_setup = read_32bit_phnx_ctrl_reg(4, 0);
|
||||
mmu_setup = mmu_setup & ~0x06;
|
||||
mmu_setup |= (value << 1);
|
||||
|
||||
/* turn on global mode */
|
||||
mmu_setup |= 0x01;
|
||||
|
||||
write_32bit_phnx_ctrl_reg(4, 0, mmu_setup);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Platform specific register setup for CPUs
|
||||
* XLR has control registers accessible with MFCR/MTCR instructions, this
|
||||
* code initialized them from the environment variable xlr.cr of form:
|
||||
* xlr.cr=reg:val[,reg:val]*, all values in hex.
|
||||
* To enable shared TLB option use xlr.shtlb=1
|
||||
*/
|
||||
void
|
||||
platform_cpu_init()
|
||||
{
|
||||
char *hw_env;
|
||||
char *start, *end;
|
||||
uint32_t reg, val;
|
||||
int thr_id = xlr_thr_id();
|
||||
|
||||
if (thr_id == 0) {
|
||||
if ((hw_env = getenv("xlr.shtlb")) != NULL) {
|
||||
start = hw_env;
|
||||
reg = strtoul(start, &end, 16);
|
||||
if (start != end && reg != 0)
|
||||
setup_tlb_resource();
|
||||
} else {
|
||||
/* By default TLB entries are shared in a core */
|
||||
setup_tlb_resource();
|
||||
}
|
||||
}
|
||||
if ((hw_env = getenv("xlr.cr")) == NULL)
|
||||
return;
|
||||
|
||||
start = hw_env;
|
||||
while (*start != '\0') {
|
||||
reg = strtoul(start, &end, 16);
|
||||
if (start == end) {
|
||||
printf("Invalid value in xlr.cr %s, cannot read a hex value at %d\n",
|
||||
hw_env, start - hw_env);
|
||||
goto err_return;
|
||||
}
|
||||
if (*end != ':') {
|
||||
printf("Invalid format in xlr.cr %s, ':' expected at pos %d\n",
|
||||
hw_env, end - hw_env);
|
||||
goto err_return;
|
||||
}
|
||||
start = end + 1;/* step over ':' */
|
||||
val = strtoul(start, &end, 16);
|
||||
if (start == end) {
|
||||
printf("Invalid value in xlr.cr %s, cannot read a hex value at pos %d\n",
|
||||
hw_env, start - hw_env);
|
||||
goto err_return;
|
||||
}
|
||||
if (*end != ',' && *end != '\0') {
|
||||
printf("Invalid format in xlr.cr %s, ',' expected at pos %d\n",
|
||||
hw_env, end - hw_env);
|
||||
goto err_return;
|
||||
}
|
||||
xlr_mtcr(reg, val);
|
||||
if (*end == ',')
|
||||
start = end + 1; /* skip over ',' */
|
||||
else
|
||||
start = end;
|
||||
}
|
||||
freeenv(hw_env);
|
||||
return;
|
||||
|
||||
err_return:
|
||||
panic("Invalid xlr.cr setting!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SMP
|
||||
extern void xlr_secondary_start(unsigned long, unsigned long, unsigned long);
|
||||
static void
|
||||
xlr_secondary_entry(void *data)
|
||||
{
|
||||
unsigned long sp, gp;
|
||||
unsigned int cpu = (xlr_cpu_id() << 2) + xlr_thr_id();
|
||||
|
||||
sp = xlr_secondary_sp[cpu];
|
||||
gp = xlr_secondary_gp[cpu];
|
||||
|
||||
xlr_secondary_start((unsigned long)mips_secondary_wait, sp, gp);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
xlr_set_boot_flags(void)
|
||||
{
|
||||
char *p;
|
||||
|
||||
for (p = getenv("boot_flags"); p && *p != '\0'; p++) {
|
||||
switch (*p) {
|
||||
case 'd':
|
||||
case 'D':
|
||||
boothowto |= RB_KDB;
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
boothowto |= RB_GDB;
|
||||
break;
|
||||
case 'v':
|
||||
case 'V':
|
||||
boothowto |= RB_VERBOSE;
|
||||
break;
|
||||
|
||||
case 's': /* single-user (default, supported for sanity) */
|
||||
case 'S':
|
||||
boothowto |= RB_SINGLE;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unrecognized boot flag '%c'.\n", *p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p)
|
||||
freeenv(p);
|
||||
|
||||
return;
|
||||
}
|
||||
extern uint32_t _end;
|
||||
|
||||
|
||||
static void
|
||||
mips_init(void)
|
||||
{
|
||||
init_param1();
|
||||
init_param2(physmem);
|
||||
|
||||
/* XXX: Catch 22. Something touches the tlb. */
|
||||
|
||||
mips_cpu_init();
|
||||
pmap_bootstrap();
|
||||
|
||||
mips_proc0_init();
|
||||
write_c0_register32(MIPS_COP_0_OSSCRATCH, 7, pcpup->pc_curthread);
|
||||
|
||||
mutex_init();
|
||||
|
||||
PMAP_LOCK_INIT(kernel_pmap);
|
||||
|
||||
#ifdef DDB
|
||||
#ifdef SMP
|
||||
setup_nmi();
|
||||
#endif /* SMP */
|
||||
kdb_init();
|
||||
if (boothowto & RB_KDB) {
|
||||
kdb_enter("Boot flags requested debugger", NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
platform_start(__register_t a0 __unused,
|
||||
__register_t a1 __unused,
|
||||
__register_t a2 __unused,
|
||||
__register_t a3 __unused)
|
||||
{
|
||||
vm_size_t physsz = 0;
|
||||
int i, j;
|
||||
struct xlr_boot1_mem_map *boot_map;
|
||||
#ifdef SMP
|
||||
uint32_t tmp;
|
||||
void (*wakeup) (void *, void *, unsigned int);
|
||||
|
||||
#endif
|
||||
/* XXX no zeroing of BSS? */
|
||||
|
||||
/* Initialize pcpu stuff */
|
||||
mips_pcpu0_init();
|
||||
|
||||
/* XXX FIXME the code below is not 64 bit clean */
|
||||
/* Save boot loader and other stuff from scratch regs */
|
||||
xlr_boot1_info = *(struct boot1_info *)read_c0_register32(MIPS_COP_0_OSSCRATCH, 0);
|
||||
cpu_mask_info = read_c0_register64(MIPS_COP_0_OSSCRATCH, 1);
|
||||
xlr_online_cpumask = read_c0_register32(MIPS_COP_0_OSSCRATCH, 2);
|
||||
xlr_run_mode = read_c0_register32(MIPS_COP_0_OSSCRATCH, 3);
|
||||
xlr_argc = read_c0_register32(MIPS_COP_0_OSSCRATCH, 4);
|
||||
xlr_argv = (char **)read_c0_register32(MIPS_COP_0_OSSCRATCH, 5);
|
||||
xlr_envp = (char **)read_c0_register32(MIPS_COP_0_OSSCRATCH, 6);
|
||||
|
||||
/* TODO: Verify the magic number here */
|
||||
/* FIXMELATER: xlr_boot1_info.magic_number */
|
||||
|
||||
/* initialize console so that we have printf */
|
||||
boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */
|
||||
|
||||
/* clockrate used by delay, so initialize it here */
|
||||
cpu_clock = xlr_boot1_info.cpu_frequency / 1000000;
|
||||
|
||||
/*
|
||||
* Note the time counter on CPU0 runs not at system clock speed, but
|
||||
* at PIC time counter speed (which is returned by
|
||||
* platform_get_frequency(). Thus we do not use
|
||||
* xlr_boot1_info.cpu_frequency here.
|
||||
*/
|
||||
mips_timer_early_init(platform_get_frequency());
|
||||
|
||||
/* Init the time counter in the PIC and local putc routine*/
|
||||
rmi_early_counter_init();
|
||||
|
||||
/* Init console please */
|
||||
cninit();
|
||||
init_static_kenv(boot1_env, sizeof(boot1_env));
|
||||
printf("Environment (from %d args):\n", xlr_argc - 1);
|
||||
if (xlr_argc == 1)
|
||||
printf("\tNone\n");
|
||||
for (i = 1; i < xlr_argc; i++) {
|
||||
char *n;
|
||||
|
||||
printf("\t%s\n", xlr_argv[i]);
|
||||
n = strsep(&xlr_argv[i], "=");
|
||||
if (xlr_argv[i] == NULL)
|
||||
setenv(n, "1");
|
||||
else
|
||||
setenv(n, xlr_argv[i]);
|
||||
}
|
||||
|
||||
xlr_set_boot_flags();
|
||||
|
||||
/* get physical memory info from boot loader */
|
||||
boot_map = (struct xlr_boot1_mem_map *)
|
||||
(unsigned long)xlr_boot1_info.psb_mem_map;
|
||||
for (i = 0, j = 0; i < boot_map->num_entries; i++, j += 2) {
|
||||
if (boot_map->physmem_map[i].type == BOOT1_MEM_RAM) {
|
||||
if (j == 14) {
|
||||
printf("*** ERROR *** memory map too large ***\n");
|
||||
break;
|
||||
}
|
||||
if (j == 0) {
|
||||
/* TODO FIXME */
|
||||
/* start after kernel end */
|
||||
phys_avail[0] = (vm_paddr_t)
|
||||
MIPS_KSEG0_TO_PHYS(&_end) + 0x20000;
|
||||
/* boot loader start */
|
||||
/* HACK to Use bootloaders memory region */
|
||||
/* TODO FIXME */
|
||||
if (boot_map->physmem_map[0].size == 0x0c000000) {
|
||||
boot_map->physmem_map[0].size = 0x0ff00000;
|
||||
}
|
||||
phys_avail[1] = boot_map->physmem_map[0].addr +
|
||||
boot_map->physmem_map[0].size;
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Can't use this code yet, because most of the fixed allocations happen from
|
||||
* the biggest physical area. If we have more than 512M memory the kernel will try
|
||||
* to map from the second are which is not in KSEG0 and not mapped
|
||||
*/
|
||||
phys_avail[j] = (vm_paddr_t)
|
||||
boot_map->physmem_map[i].addr;
|
||||
phys_avail[j + 1] = phys_avail[j] +
|
||||
boot_map->physmem_map[i].size;
|
||||
#if 0 /* FIXME TOD0 */
|
||||
phys_avail[j] = phys_avail[j + 1] = 0;
|
||||
#endif
|
||||
}
|
||||
physsz += boot_map->physmem_map[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME XLR TODO */
|
||||
phys_avail[j] = phys_avail[j + 1] = 0;
|
||||
realmem = physmem = btoc(physsz);
|
||||
|
||||
/* Store pcpu in scratch 5 */
|
||||
write_c0_register32(MIPS_COP_0_OSSCRATCH, 5, pcpup);
|
||||
|
||||
/* Set up hz, among others. */
|
||||
mips_init();
|
||||
|
||||
#ifdef SMP
|
||||
/*
|
||||
* If thread 0 of any core is not available then mark whole core as
|
||||
* not available
|
||||
*/
|
||||
tmp = xlr_boot1_info.cpu_online_map;
|
||||
for (i = 4; i < MAXCPU; i += 4) {
|
||||
if ((tmp & (0xf << i)) && !(tmp & (0x1 << i))) {
|
||||
/*
|
||||
* Oopps.. thread 0 is not available. Disable whole
|
||||
* core
|
||||
*/
|
||||
tmp = tmp & ~(0xf << i);
|
||||
printf("WARNING: Core %d is disabled because thread 0"
|
||||
" of this core is not enabled.\n", i / 4);
|
||||
}
|
||||
}
|
||||
xlr_boot1_info.cpu_online_map = tmp;
|
||||
|
||||
/* Wakeup Other cpus, and put them in bsd park code. */
|
||||
for (i = 1, j = 1; i < 32; i++) {
|
||||
/* Allocate stack for all other cpus from fbsd kseg0 memory. */
|
||||
if ((1U << i) & xlr_boot1_info.cpu_online_map) {
|
||||
xlr_secondary_gp[i] =
|
||||
pmap_steal_memory(PAGE_SIZE);
|
||||
if (!xlr_secondary_gp[i])
|
||||
panic("Allocation failed for secondary cpu stacks");
|
||||
xlr_secondary_sp[i] =
|
||||
xlr_secondary_gp[i] + PAGE_SIZE - CALLFRAME_SIZ;
|
||||
xlr_secondary_gp[i] = (unsigned long)&_gp;
|
||||
/* Build ltop and ptol cpu map. */
|
||||
cpu_ltop_map[j] = i;
|
||||
cpu_ptol_map[i] = j;
|
||||
if ((i & 0x3) == 0) /* store thread0 of each core */
|
||||
xlr_core_cpu_mask |= (1 << j);
|
||||
mips_cpu_logical_mask |= (1 << j);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
mips_cpu_online_mask |= xlr_boot1_info.cpu_online_map;
|
||||
wakeup = ((void (*) (void *, void *, unsigned int))
|
||||
(unsigned long)(xlr_boot1_info.wakeup));
|
||||
printf("Waking up CPUs 0x%llx.\n", xlr_boot1_info.cpu_online_map & ~(0x1U));
|
||||
if (xlr_boot1_info.cpu_online_map & ~(0x1U))
|
||||
wakeup(xlr_secondary_entry, 0,
|
||||
(unsigned int)xlr_boot1_info.cpu_online_map);
|
||||
#endif
|
||||
|
||||
/* xlr specific post initialization */
|
||||
/*
|
||||
* The expectation is that mutex_init() is already done in
|
||||
* mips_init() XXX NOTE: We may need to move this to SMP based init
|
||||
* code for each CPU, later.
|
||||
*/
|
||||
rmi_spin_mutex_safe = 1;
|
||||
on_chip_init();
|
||||
mips_timer_init_params(platform_get_frequency(), 0);
|
||||
printf("Platform specific startup now completes\n");
|
||||
}
|
||||
|
||||
void
|
||||
platform_identify(void)
|
||||
{
|
||||
printf("Board [%d:%d], processor 0x%08x\n", (int)xlr_boot1_info.board_major_version,
|
||||
(int)xlr_boot1_info.board_minor_version, mips_rd_prid());
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX Maybe return the state of the watchdog in enter, and pass it to
|
||||
* exit? Like spl().
|
||||
*/
|
||||
void
|
||||
platform_trap_enter(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
platform_trap_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void
|
||||
platform_update_intrmask(int intr)
|
||||
{
|
||||
write_c0_eimr64(read_c0_eimr64() | (1ULL<<intr));
|
||||
}
|
||||
*/
|
||||
|
||||
void
|
||||
disable_msgring_int(void *arg);
|
||||
void
|
||||
enable_msgring_int(void *arg);
|
||||
void xlr_msgring_handler(struct trapframe *tf);
|
||||
void msgring_process_fast_intr(void *arg);
|
||||
|
||||
struct msgring_ithread {
|
||||
struct thread *i_thread;
|
||||
u_int i_pending;
|
||||
u_int i_flags;
|
||||
int i_cpu;
|
||||
};
|
||||
struct msgring_ithread msgring_ithreads[MAXCPU];
|
||||
char ithd_name[MAXCPU][32];
|
||||
|
||||
void
|
||||
msgring_process_fast_intr(void *arg)
|
||||
{
|
||||
int cpu = PCPU_GET(cpuid);
|
||||
volatile struct msgring_ithread *it;
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
|
||||
/* wakeup an appropriate intr_thread for processing this interrupt */
|
||||
it = (volatile struct msgring_ithread *)&msgring_ithreads[cpu];
|
||||
td = it->i_thread;
|
||||
p = td->td_proc;
|
||||
|
||||
/*
|
||||
* Interrupt thread will enable the interrupts after processing all
|
||||
* messages
|
||||
*/
|
||||
disable_msgring_int(NULL);
|
||||
it->i_pending = 1;
|
||||
if (TD_AWAITING_INTR(td)) {
|
||||
thread_lock(td);
|
||||
CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid,
|
||||
p->p_comm);
|
||||
TD_CLR_IWAIT(td);
|
||||
sched_add(td, SRQ_INTR);
|
||||
thread_unlock(td);
|
||||
} else {
|
||||
CTR4(KTR_INTR, "%s: pid %d (%s): state %d",
|
||||
__func__, p->p_pid, p->p_comm, td->td_state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define MIT_DEAD 4
|
||||
static void
|
||||
msgring_process(void *arg)
|
||||
{
|
||||
volatile struct msgring_ithread *ithd;
|
||||
struct thread *td;
|
||||
struct proc *p;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
ithd = (volatile struct msgring_ithread *)arg;
|
||||
KASSERT(ithd->i_thread == td,
|
||||
("%s:msg_ithread and proc linkage out of sync", __func__));
|
||||
|
||||
/* First bind this thread to the right CPU */
|
||||
thread_lock(td);
|
||||
sched_bind(td, ithd->i_cpu);
|
||||
thread_unlock(td);
|
||||
|
||||
//printf("Started %s on CPU %d\n", __FUNCTION__, ithd->i_cpu);
|
||||
|
||||
while (1) {
|
||||
if (ithd->i_flags & MIT_DEAD) {
|
||||
CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__,
|
||||
p->p_pid, p->p_comm);
|
||||
kthread_exit();
|
||||
}
|
||||
while (ithd->i_pending) {
|
||||
/*
|
||||
* This might need a full read and write barrier to
|
||||
* make sure that this write posts before any of the
|
||||
* memory or device accesses in the handlers.
|
||||
*/
|
||||
atomic_store_rel_int(&ithd->i_pending, 0);
|
||||
xlr_msgring_handler(NULL);
|
||||
}
|
||||
if (!ithd->i_pending && !(ithd->i_flags & MIT_DEAD)) {
|
||||
thread_lock(td);
|
||||
sched_class(td, PRI_ITHD);
|
||||
TD_SET_IWAIT(td);
|
||||
thread_unlock(td);
|
||||
enable_msgring_int(NULL);
|
||||
mi_switch(SW_VOL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void
|
||||
platform_prep_smp_launch(void)
|
||||
{
|
||||
int cpu;
|
||||
uint32_t cpu_mask;
|
||||
struct msgring_ithread *ithd;
|
||||
struct thread *td;
|
||||
struct proc *p;
|
||||
int error;
|
||||
|
||||
cpu_mask = PCPU_GET(cpumask) | PCPU_GET(other_cpus);
|
||||
|
||||
/* Create kernel threads for message ring interrupt processing */
|
||||
/* Currently create one task for thread 0 of each core */
|
||||
for (cpu = 0; cpu < MAXCPU; cpu += 1) {
|
||||
|
||||
if (!((1 << cpu) & cpu_mask))
|
||||
continue;
|
||||
|
||||
if ((cpu_ltop_map[cpu] % 4) != 0)
|
||||
continue;
|
||||
|
||||
ithd = &msgring_ithreads[cpu];
|
||||
sprintf(ithd_name[cpu], "msg_intr%d", cpu);
|
||||
error = kproc_create(msgring_process,
|
||||
(void *)ithd,
|
||||
&p,
|
||||
(RFSTOPPED | RFHIGHPID),
|
||||
2,
|
||||
ithd_name[cpu]);
|
||||
|
||||
if (error)
|
||||
panic("kproc_create() failed with %d", error);
|
||||
td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */
|
||||
|
||||
thread_lock(td);
|
||||
sched_class(td, PRI_ITHD);
|
||||
TD_SET_IWAIT(td);
|
||||
thread_unlock(td);
|
||||
ithd->i_thread = td;
|
||||
ithd->i_pending = 0;
|
||||
ithd->i_cpu = cpu;
|
||||
CTR2(KTR_INTR, "%s: created %s", __func__, ithd_name[cpu]);
|
||||
}
|
||||
}
|
426
sys/mips/rmi/xlr_pci.c
Normal file
426
sys/mips/rmi/xlr_pci.c
Normal file
@ -0,0 +1,426 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bus.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <mips/rmi/rmi_mips_exts.h>
|
||||
#include <machine/cpuregs.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <sys/rman.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcib_private.h>
|
||||
|
||||
#include <mips/rmi/iomap.h>
|
||||
#include <mips/rmi/pic.h>
|
||||
#include <mips/rmi/shared_structs.h>
|
||||
#include <mips/rmi/board.h>
|
||||
#include <mips/rmi/pcibus.h>
|
||||
#include "pcib_if.h"
|
||||
|
||||
#define LSU_CFG0_REGID 0
|
||||
#define LSU_CERRLOG_REGID 9
|
||||
#define LSU_CERROVF_REGID 10
|
||||
#define LSU_CERRINT_REGID 11
|
||||
#define SWAP32(x)\
|
||||
(((x) & 0xff000000) >> 24) | \
|
||||
(((x) & 0x000000ff) << 24) | \
|
||||
(((x) & 0x0000ff00) << 8) | \
|
||||
(((x) & 0x00ff0000) >> 8)
|
||||
|
||||
|
||||
/* MSI support */
|
||||
|
||||
#define MSI_MIPS_ADDR_DEST 0x000ff000
|
||||
#define MSI_MIPS_ADDR_RH 0x00000008
|
||||
#define MSI_MIPS_ADDR_RH_OFF 0x00000000
|
||||
#define MSI_MIPS_ADDR_RH_ON 0x00000008
|
||||
#define MSI_MIPS_ADDR_DM 0x00000004
|
||||
#define MSI_MIPS_ADDR_DM_PHYSICAL 0x00000000
|
||||
#define MSI_MIPS_ADDR_DM_LOGICAL 0x00000004
|
||||
|
||||
/* Fields in data for Intel MSI messages. */
|
||||
#define MSI_MIPS_DATA_TRGRMOD 0x00008000 /* Trigger mode */
|
||||
#define MSI_MIPS_DATA_TRGREDG 0x00000000 /* edge */
|
||||
#define MSI_MIPS_DATA_TRGRLVL 0x00008000 /* level */
|
||||
|
||||
#define MSI_MIPS_DATA_LEVEL 0x00004000 /* Polarity. */
|
||||
#define MSI_MIPS_DATA_DEASSERT 0x00000000
|
||||
#define MSI_MIPS_DATA_ASSERT 0x00004000
|
||||
|
||||
#define MSI_MIPS_DATA_DELMOD 0x00000700 /* Delivery Mode */
|
||||
#define MSI_MIPS_DATA_DELFIXED 0x00000000 /* fixed */
|
||||
#define MSI_MIPS_DATA_DELLOPRI 0x00000100 /* lowest priority */
|
||||
|
||||
#define MSI_MIPS_DATA_INTVEC 0x000000ff
|
||||
|
||||
/*
|
||||
* Build Intel MSI message and data values from a source. AMD64 systems
|
||||
* seem to be compatible, so we use the same function for both.
|
||||
*/
|
||||
#define MIPS_MSI_ADDR(cpu) \
|
||||
(MSI_MIPS_ADDR_BASE | (cpu) << 12 | \
|
||||
MSI_MIPS_ADDR_RH_OFF | MSI_MIPS_ADDR_DM_PHYSICAL)
|
||||
|
||||
#define MIPS_MSI_DATA(irq) \
|
||||
(MSI_MIPS_DATA_TRGRLVL | MSI_MIPS_DATA_DELFIXED | \
|
||||
MSI_MIPS_DATA_ASSERT | (irq))
|
||||
|
||||
struct xlr_hose_softc {
|
||||
int junk; /* no softc */
|
||||
};
|
||||
static devclass_t pcib_devclass;
|
||||
static int pci_bus_status = 0;
|
||||
static void *pci_config_base;
|
||||
|
||||
static uint32_t pci_cfg_read_32bit(uint32_t addr);
|
||||
static void pci_cfg_write_32bit(uint32_t addr, uint32_t data);
|
||||
|
||||
static int
|
||||
xlr_pcib_probe(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "xlr system bridge controller");
|
||||
|
||||
pci_init_resources();
|
||||
pci_config_base = (void *)MIPS_PHYS_TO_KSEG1(DEFAULT_PCI_CONFIG_BASE);
|
||||
pci_bus_status = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xlr_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t * result)
|
||||
{
|
||||
#if 0
|
||||
device_printf(dev, "xlr_pcib_read_ivar : read ivar %d for child %s\n", which, device_get_nameunit(child));
|
||||
#endif
|
||||
switch (which) {
|
||||
case PCIB_IVAR_BUS:
|
||||
*result = 0;
|
||||
return 0;
|
||||
}
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
static int
|
||||
xlr_pcib_maxslots(device_t dev)
|
||||
{
|
||||
if (xlr_board_info.is_xls)
|
||||
return 4;
|
||||
else
|
||||
return 32;
|
||||
}
|
||||
|
||||
#define pci_cfg_offset(bus,slot,devfn,where) (((bus)<<16) + ((slot) << 11)+((devfn)<<8)+(where))
|
||||
|
||||
static __inline__ void
|
||||
disable_and_clear_cache_error(void)
|
||||
{
|
||||
uint64_t lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID);
|
||||
|
||||
lsu_cfg0 = lsu_cfg0 & ~0x2e;
|
||||
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0);
|
||||
/* Clear cache error log */
|
||||
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0);
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
clear_and_enable_cache_error(void)
|
||||
{
|
||||
uint64_t lsu_cfg0 = 0;
|
||||
|
||||
/* first clear the cache error logging register */
|
||||
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0);
|
||||
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERROVF_REGID, 0);
|
||||
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRINT_REGID, 0);
|
||||
|
||||
lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID);
|
||||
lsu_cfg0 = lsu_cfg0 | 0x2e;
|
||||
write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
phoenix_pciread(u_int b, u_int s, u_int f,
|
||||
u_int reg, int width)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
|
||||
if ((width == 2) && (reg & 1))
|
||||
return 0xFFFFFFFF;
|
||||
else if ((width == 4) && (reg & 3))
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
if (pci_bus_status)
|
||||
data = pci_cfg_read_32bit(pci_cfg_offset(b, s, f, reg));
|
||||
else
|
||||
data = 0xFFFFFFFF;
|
||||
|
||||
if (width == 1)
|
||||
return ((data >> ((reg & 3) << 3)) & 0xff);
|
||||
else if (width == 2)
|
||||
return ((data >> ((reg & 3) << 3)) & 0xffff);
|
||||
else
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
phoenix_pciwrite(u_int b, u_int s, u_int f,
|
||||
u_int reg, u_int val, int width)
|
||||
{
|
||||
uint32_t cfgaddr = pci_cfg_offset(b, s, f, reg);
|
||||
uint32_t data = 0;
|
||||
|
||||
if ((width == 2) && (reg & 1))
|
||||
return;
|
||||
else if ((width == 4) && (reg & 3))
|
||||
return;
|
||||
|
||||
if (!pci_bus_status)
|
||||
return;
|
||||
|
||||
if (width == 1) {
|
||||
data = pci_cfg_read_32bit(cfgaddr);
|
||||
data = (data & ~(0xff << ((reg & 3) << 3))) |
|
||||
(val << ((reg & 3) << 3));
|
||||
} else if (width == 2) {
|
||||
data = pci_cfg_read_32bit(cfgaddr);
|
||||
data = (data & ~(0xffff << ((reg & 3) << 3))) |
|
||||
(val << ((reg & 3) << 3));
|
||||
} else {
|
||||
data = val;
|
||||
}
|
||||
|
||||
pci_cfg_write_32bit(cfgaddr, data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
pci_cfg_read_32bit(uint32_t addr)
|
||||
{
|
||||
uint32_t temp = 0;
|
||||
uint32_t *p = (uint32_t *) ((uint32_t) pci_config_base + (addr & ~3));
|
||||
uint64_t cerr_cpu_log = 0;
|
||||
|
||||
disable_and_clear_cache_error();
|
||||
|
||||
temp = SWAP32(*p);
|
||||
|
||||
/* Read cache err log */
|
||||
cerr_cpu_log = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID);
|
||||
|
||||
if (cerr_cpu_log) {
|
||||
/* Device don't exist. */
|
||||
temp = ~0x0;
|
||||
}
|
||||
clear_and_enable_cache_error();
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pci_cfg_write_32bit(uint32_t addr, uint32_t data)
|
||||
{
|
||||
unsigned int *p = (unsigned int *)((uint32_t) pci_config_base + (addr & ~3));
|
||||
|
||||
*p = SWAP32(data);
|
||||
}
|
||||
|
||||
static u_int32_t
|
||||
xlr_pcib_read_config(device_t dev, u_int b, u_int s, u_int f,
|
||||
u_int reg, int width)
|
||||
{
|
||||
return phoenix_pciread(b, s, f, reg, width);
|
||||
}
|
||||
|
||||
static void
|
||||
xlr_pcib_write_config(device_t dev, u_int b, u_int s, u_int f,
|
||||
u_int reg, u_int32_t val, int width)
|
||||
{
|
||||
phoenix_pciwrite(b, s, f, reg, val, width);
|
||||
}
|
||||
|
||||
static int
|
||||
xlr_pcib_attach(device_t dev)
|
||||
{
|
||||
device_add_child(dev, "pci", 0);
|
||||
bus_generic_attach(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PCIE_LINK_STATE 0x4000
|
||||
|
||||
static void
|
||||
xlr_pcib_identify(driver_t * driver, device_t parent)
|
||||
{
|
||||
xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET);
|
||||
xlr_reg_t reg_link0 = xlr_read_reg(pcie_mmio_le, (0x80 >> 2));
|
||||
xlr_reg_t reg_link1 = xlr_read_reg(pcie_mmio_le, (0x84 >> 2));
|
||||
|
||||
if ((uint16_t) reg_link0 & PCIE_LINK_STATE) {
|
||||
device_printf(parent, "Link 0 up\n");
|
||||
}
|
||||
if ((uint16_t) reg_link1 & PCIE_LINK_STATE) {
|
||||
device_printf(parent, "Link 1 up\n");
|
||||
}
|
||||
BUS_ADD_CHILD(parent, 0, "pcib", 0);
|
||||
|
||||
}
|
||||
static int
|
||||
xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs);
|
||||
static int
|
||||
xlr_release_msi(device_t pcib, device_t dev, int count, int *irqs);
|
||||
|
||||
static int
|
||||
xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs)
|
||||
{
|
||||
int pciirq;
|
||||
int i;
|
||||
device_t parent, tmp;
|
||||
|
||||
|
||||
/* find the lane on which the slot is connected to */
|
||||
tmp = dev;
|
||||
while (1) {
|
||||
parent = device_get_parent(tmp);
|
||||
if (parent == NULL || parent == pcib) {
|
||||
device_printf(dev, "Cannot find parent bus\n");
|
||||
return ENXIO;
|
||||
}
|
||||
if (strcmp(device_get_nameunit(parent), "pci0") == 0)
|
||||
break;
|
||||
tmp = parent;
|
||||
}
|
||||
|
||||
switch (pci_get_slot(tmp)) {
|
||||
case 0:
|
||||
pciirq = PIC_PCIE_LINK0_IRQ;
|
||||
break;
|
||||
case 1:
|
||||
pciirq = PIC_PCIE_LINK1_IRQ;
|
||||
break;
|
||||
case 2:
|
||||
pciirq = PIC_PCIE_LINK2_IRQ;
|
||||
break;
|
||||
case 3:
|
||||
pciirq = PIC_PCIE_LINK3_IRQ;
|
||||
break;
|
||||
default:
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
irqs[0] = pciirq;
|
||||
/*
|
||||
* For now put in some fixed values for the other requested MSI,
|
||||
* TODO handle multiple messages
|
||||
*/
|
||||
for (i = 1; i < count; i++)
|
||||
irqs[i] = pciirq + 64 * i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xlr_release_msi(device_t pcib, device_t dev, int count, int *irqs)
|
||||
{
|
||||
device_printf(dev, "%s: msi release %d\n", device_get_nameunit(pcib), count);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
xlr_map_msi(device_t pcib, device_t dev, int irq, uint64_t * addr, uint32_t * data);
|
||||
|
||||
static int
|
||||
xlr_map_msi(device_t pcib, device_t dev, int irq, uint64_t * addr, uint32_t * data)
|
||||
{
|
||||
switch (irq) {
|
||||
case PIC_PCIE_LINK0_IRQ:
|
||||
case PIC_PCIE_LINK1_IRQ:
|
||||
case PIC_PCIE_LINK2_IRQ:
|
||||
case PIC_PCIE_LINK3_IRQ:
|
||||
*addr = MIPS_MSI_ADDR(0);
|
||||
*data = MIPS_MSI_DATA(irq);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
device_printf(dev, "%s: map_msi for irq %d - ignored", device_get_nameunit(pcib),
|
||||
irq);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static device_method_t xlr_pcib_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_identify, xlr_pcib_identify),
|
||||
DEVMETHOD(device_probe, xlr_pcib_probe),
|
||||
DEVMETHOD(device_attach, xlr_pcib_attach),
|
||||
|
||||
/* Bus interface */
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
DEVMETHOD(bus_read_ivar, xlr_pcib_read_ivar),
|
||||
DEVMETHOD(bus_alloc_resource, xlr_pci_alloc_resource),
|
||||
DEVMETHOD(bus_release_resource, pci_release_resource),
|
||||
DEVMETHOD(bus_activate_resource, pci_activate_resource),
|
||||
DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
|
||||
DEVMETHOD(bus_setup_intr, mips_platform_pci_setup_intr),
|
||||
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
|
||||
|
||||
/* pcib interface */
|
||||
DEVMETHOD(pcib_maxslots, xlr_pcib_maxslots),
|
||||
DEVMETHOD(pcib_read_config, xlr_pcib_read_config),
|
||||
DEVMETHOD(pcib_write_config, xlr_pcib_write_config),
|
||||
|
||||
DEVMETHOD(pcib_route_interrupt, mips_pci_route_interrupt),
|
||||
|
||||
DEVMETHOD(pcib_alloc_msi, xlr_alloc_msi),
|
||||
DEVMETHOD(pcib_release_msi, xlr_release_msi),
|
||||
DEVMETHOD(pcib_map_msi, xlr_map_msi),
|
||||
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static driver_t xlr_pcib_driver = {
|
||||
"pcib",
|
||||
xlr_pcib_methods,
|
||||
sizeof(struct xlr_hose_softc),
|
||||
};
|
||||
|
||||
DRIVER_MODULE(pcib, nexus, xlr_pcib_driver, pcib_devclass, 0, 0);
|
336
sys/mips/rmi/xlrconfig.h
Normal file
336
sys/mips/rmi/xlrconfig.h
Normal file
@ -0,0 +1,336 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 RMI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of RMI Corporation, nor the names of its contributors,
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RMI_BSD */
|
||||
#ifndef XLRCONFIG_H
|
||||
#define XLRCONFIG_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <mips/rmi/shared_structs.h>
|
||||
#include <mips/rmi/shared_structs_func.h>
|
||||
|
||||
#define read_c0_register32(reg, sel) \
|
||||
({ unsigned int __rv; \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set mips32\n\t" \
|
||||
"mfc0\t%0,$%1,%2\n\t" \
|
||||
".set\tpop" \
|
||||
: "=r" (__rv) : "i" (reg), "i" (sel) ); \
|
||||
__rv;})
|
||||
|
||||
#define write_c0_register32(reg, sel, value) \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set mips32\n\t" \
|
||||
"mtc0\t%0,$%1,%2\n\t" \
|
||||
".set\tpop" \
|
||||
: : "r" (value), "i" (reg), "i" (sel) );
|
||||
|
||||
#define read_c0_register64(reg, sel) \
|
||||
({ unsigned int __high, __low; \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set mips64\n\t" \
|
||||
"dmfc0\t $8, $%2, %3\n\t" \
|
||||
"dsrl32\t%0, $8, 0\n\t" \
|
||||
"dsll32\t$8, $8, 0\n\t" \
|
||||
"dsrl32\t%1, $8, 0\n\t" \
|
||||
".set\tpop" \
|
||||
: "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\
|
||||
(((unsigned long long)__high << 32) | __low);})
|
||||
|
||||
#define write_c0_register64(reg, sel, value) \
|
||||
do{ \
|
||||
unsigned int __high = val>>32; \
|
||||
unsigned int __low = val & 0xffffffff; \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set mips64\n\t" \
|
||||
"dsll32\t$8, %1, 0\n\t" \
|
||||
"dsll32\t$9, %0, 0\n\t" \
|
||||
"or\t $8, $8, $9\n\t" \
|
||||
"dmtc0\t $8, $%2, %3\n\t" \
|
||||
".set\tpop" \
|
||||
:: "r"(high), "r"(low), "i"(reg), "i"(sel):"$8", "$9");\
|
||||
} while(0)
|
||||
|
||||
#define read_c2_register32(reg, sel) \
|
||||
({ unsigned int __rv; \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set mips32\n\t" \
|
||||
"mfc2\t%0,$%1,%2\n\t" \
|
||||
".set\tpop" \
|
||||
: "=r" (__rv) : "i" (reg), "i" (sel) ); \
|
||||
__rv;})
|
||||
|
||||
#define write_c2_register32(reg, sel, value) \
|
||||
__asm__ __volatile__( \
|
||||
".set\tpush\n\t" \
|
||||
".set mips32\n\t" \
|
||||
"mtc2\t%0,$%1,%2\n\t" \
|
||||
".set\tpop" \
|
||||
: : "r" (value), "i" (reg), "i" (sel) );
|
||||
|
||||
#define read_c2_register64(reg, sel) \
|
||||
({ unsigned int __high, __low; \
|
||||
__asm__ __volatile__( \
|
||||
".set mips64\n\t" \
|
||||
"dmfc2\t $8, $%2, %3\n\t" \
|
||||
"dsrl32\t%0, $8, 0\n\t" \
|
||||
"dsll32\t$8, $8, 0\n\t" \
|
||||
"dsrl32\t%1, $8, 0\n\t" \
|
||||
".set\tmips0" \
|
||||
: "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\
|
||||
(((unsigned long long)__high << 32) | __low);})
|
||||
|
||||
#define write_c2_register64(reg, sel, value) \
|
||||
do{ \
|
||||
unsigned int __high = value>>32; \
|
||||
unsigned int __low = value & 0xffffffff; \
|
||||
__asm__ __volatile__( \
|
||||
".set mips64\n\t" \
|
||||
"dsll32\t$8, %1, 0\n\t" \
|
||||
"dsll32\t$9, %0, 0\n\t" \
|
||||
"dsrl32\t$8, $8, 0\n\t" \
|
||||
"or\t $8, $8, $9\n\t" \
|
||||
"dmtc2\t $8, $%2, %3\n\t" \
|
||||
".set\tmips0" \
|
||||
:: "r"(__high), "r"(__low), \
|
||||
"i"(reg), "i"(sel) \
|
||||
:"$8", "$9"); \
|
||||
} while(0)
|
||||
|
||||
#if 0
|
||||
#define xlr_processor_id() \
|
||||
({int __id; \
|
||||
__asm__ __volatile__ ( \
|
||||
".set push\n" \
|
||||
".set noreorder\n" \
|
||||
".word 0x40088007\n" \
|
||||
"srl $8, $8, 10\n" \
|
||||
"andi %0, $8, 0x3f\n" \
|
||||
".set pop\n" \
|
||||
: "=r" (__id) : : "$8"); \
|
||||
__id;})
|
||||
#endif
|
||||
|
||||
#define xlr_cpu_id() \
|
||||
({int __id; \
|
||||
__asm__ __volatile__ ( \
|
||||
".set push\n" \
|
||||
".set noreorder\n" \
|
||||
".word 0x40088007\n" \
|
||||
"srl $8, $8, 4\n" \
|
||||
"andi %0, $8, 0x7\n" \
|
||||
".set pop\n" \
|
||||
: "=r" (__id) : : "$8"); \
|
||||
__id;})
|
||||
|
||||
#define xlr_thr_id() \
|
||||
({int __id; \
|
||||
__asm__ __volatile__ ( \
|
||||
".set push\n" \
|
||||
".set noreorder\n" \
|
||||
".word 0x40088007\n" \
|
||||
"andi %0, $8, 0x03\n" \
|
||||
".set pop\n" \
|
||||
: "=r" (__id) : : "$8"); \
|
||||
__id;})
|
||||
|
||||
|
||||
/* Additional registers on the XLR */
|
||||
#define MIPS_COP_0_OSSCRATCH 22
|
||||
|
||||
#define XLR_CACHELINE_SIZE 32
|
||||
|
||||
#define XLR_MAX_CORES 8
|
||||
|
||||
/* functions to write to and read from the extended
|
||||
* cp0 registers.
|
||||
* EIRR : Extended Interrupt Request Register
|
||||
* cp0 register 9 sel 6
|
||||
* bits 0...7 are same as cause register 8...15
|
||||
* EIMR : Extended Interrupt Mask Register
|
||||
* cp0 register 9 sel 7
|
||||
* bits 0...7 are same as status register 8...15
|
||||
*/
|
||||
|
||||
static inline uint64_t
|
||||
read_c0_eirr64(void)
|
||||
{
|
||||
__uint32_t high, low;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set push\n"
|
||||
".set noreorder\n"
|
||||
".set noat\n"
|
||||
".set mips4\n"
|
||||
|
||||
".word 0x40214806 \n\t"
|
||||
"nop \n\t"
|
||||
"dsra32 %0, $1, 0 \n\t"
|
||||
"sll %1, $1, 0 \n\t"
|
||||
|
||||
".set pop\n"
|
||||
|
||||
: "=r"(high), "=r"(low)
|
||||
);
|
||||
|
||||
return (((__uint64_t) high) << 32) | low;
|
||||
}
|
||||
|
||||
static inline __uint64_t
|
||||
read_c0_eimr64(void)
|
||||
{
|
||||
__uint32_t high, low;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set push\n"
|
||||
".set noreorder\n"
|
||||
".set noat\n"
|
||||
".set mips4\n"
|
||||
|
||||
".word 0x40214807 \n\t"
|
||||
"nop \n\t"
|
||||
"dsra32 %0, $1, 0 \n\t"
|
||||
"sll %1, $1, 0 \n\t"
|
||||
|
||||
".set pop\n"
|
||||
|
||||
: "=r"(high), "=r"(low)
|
||||
);
|
||||
|
||||
return (((__uint64_t) high) << 32) | low;
|
||||
}
|
||||
|
||||
static inline void
|
||||
write_c0_eirr64(__uint64_t value)
|
||||
{
|
||||
__uint32_t low, high;
|
||||
|
||||
high = value >> 32;
|
||||
low = value & 0xffffffff;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set push\n"
|
||||
".set noreorder\n"
|
||||
".set noat\n"
|
||||
".set mips4\n\t"
|
||||
|
||||
"dsll32 $2, %1, 0 \n\t"
|
||||
"dsll32 $1, %0, 0 \n\t"
|
||||
"dsrl32 $2, $2, 0 \n\t"
|
||||
"or $1, $1, $2 \n\t"
|
||||
".word 0x40a14806 \n\t"
|
||||
"nop \n\t"
|
||||
|
||||
".set pop\n"
|
||||
|
||||
:
|
||||
: "r"(high), "r"(low)
|
||||
: "$1", "$2");
|
||||
}
|
||||
|
||||
static inline void
|
||||
write_c0_eimr64(__uint64_t value)
|
||||
{
|
||||
__uint32_t low, high;
|
||||
|
||||
high = value >> 32;
|
||||
low = value & 0xffffffff;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set push\n"
|
||||
".set noreorder\n"
|
||||
".set noat\n"
|
||||
".set mips4\n\t"
|
||||
|
||||
"dsll32 $2, %1, 0 \n\t"
|
||||
"dsll32 $1, %0, 0 \n\t"
|
||||
"dsrl32 $2, $2, 0 \n\t"
|
||||
"or $1, $1, $2 \n\t"
|
||||
".word 0x40a14807 \n\t"
|
||||
"nop \n\t"
|
||||
|
||||
".set pop\n"
|
||||
|
||||
:
|
||||
: "r"(high), "r"(low)
|
||||
: "$1", "$2");
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
xlr_test_and_set(int *lock)
|
||||
{
|
||||
int oldval = 0;
|
||||
|
||||
__asm__ __volatile__(".set push\n"
|
||||
".set noreorder\n"
|
||||
"move $9, %2\n"
|
||||
"li $8, 1\n"
|
||||
// "swapw $8, $9\n"
|
||||
".word 0x71280014\n"
|
||||
"move %1, $8\n"
|
||||
".set pop\n"
|
||||
: "+m"(*lock), "=r"(oldval)
|
||||
: "r"((unsigned long)lock)
|
||||
: "$8", "$9"
|
||||
);
|
||||
|
||||
return (oldval == 0 ? 1 /* success */ : 0 /* failure */ );
|
||||
}
|
||||
|
||||
static __inline__ uint32_t
|
||||
xlr_mfcr(uint32_t reg)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"move $8, %1\n"
|
||||
".word 0x71090018\n"
|
||||
"move %0, $9\n"
|
||||
: "=r"(val)
|
||||
: "r"(reg):"$8", "$9");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
xlr_mtcr(uint32_t reg, uint32_t val)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"move $8, %1\n"
|
||||
"move $9, %0\n"
|
||||
".word 0x71090019\n"
|
||||
:: "r"(val), "r"(reg)
|
||||
: "$8", "$9");
|
||||
}
|
||||
|
||||
#endif
|
303
sys/mips/rmi/xls_ehci.c
Normal file
303
sys/mips/rmi/xls_ehci.c
Normal file
@ -0,0 +1,303 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Lennart Augustsson (augustss@carlstedt.se) at
|
||||
* Carlstedt Research & Technology.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.18.2.4 2008/04/23 18:54:51 jhb Exp $");
|
||||
|
||||
/*
|
||||
* USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
|
||||
*
|
||||
* The EHCI 1.0 spec can be found at
|
||||
* http://developer.intel.com/technology/usb/download/ehci-r10.pdf
|
||||
* and the USB 2.0 spec at
|
||||
* http://www.usb.org/developers/docs/usb_20.zip
|
||||
*/
|
||||
|
||||
/* The low level controller code for EHCI has been split into
|
||||
* PCI probes and EHCI specific code. This was done to facilitate the
|
||||
* sharing of code between *BSD's
|
||||
*/
|
||||
|
||||
#include "opt_bus.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/lockmgr.h>
|
||||
#include <machine/bus.h>
|
||||
#include <sys/rman.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
/*#include <dev/usb/usbdivar.h> */
|
||||
/*#include <dev/usb/usb_mem.h> */
|
||||
|
||||
#include <mips/rmi/ehcireg.h>
|
||||
#include <mips/rmi/ehcivar.h>
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
#define EHCI_DEBUG USB_DEBUG
|
||||
#define DPRINTF(x) do { if (ehcidebug) logprintf x; } while (0)
|
||||
extern int ehcidebug;
|
||||
|
||||
#else
|
||||
#define DPRINTF(x)
|
||||
#endif
|
||||
|
||||
static int ehci_xls_attach(device_t self);
|
||||
static int ehci_xls_detach(device_t self);
|
||||
static int ehci_xls_shutdown(device_t self);
|
||||
static int ehci_xls_suspend(device_t self);
|
||||
static int ehci_xls_resume(device_t self);
|
||||
static void ehci_xls_givecontroller(device_t self);
|
||||
static void ehci_xls_takecontroller(device_t self);
|
||||
|
||||
static int
|
||||
ehci_xls_suspend(device_t self)
|
||||
{
|
||||
ehci_softc_t *sc = device_get_softc(self);
|
||||
int err;
|
||||
|
||||
err = bus_generic_suspend(self);
|
||||
if (err)
|
||||
return (err);
|
||||
ehci_power(PWR_SUSPEND, sc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ehci_xls_resume(device_t self)
|
||||
{
|
||||
ehci_softc_t *sc = device_get_softc(self);
|
||||
|
||||
ehci_xls_takecontroller(self);
|
||||
ehci_power(PWR_RESUME, sc);
|
||||
bus_generic_resume(self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ehci_xls_shutdown(device_t self)
|
||||
{
|
||||
ehci_softc_t *sc = device_get_softc(self);
|
||||
int err;
|
||||
|
||||
err = bus_generic_shutdown(self);
|
||||
if (err)
|
||||
return (err);
|
||||
ehci_shutdown(sc);
|
||||
ehci_xls_givecontroller(self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const char *xlr_usb_dev_desc = "RMI XLR USB 2.0 controller";
|
||||
static const char *xlr_vendor_desc = "RMI Corp";
|
||||
static int
|
||||
ehci_xls_probe(device_t self)
|
||||
{
|
||||
|
||||
/* TODO see if usb is enabled on the board */
|
||||
device_set_desc(self, xlr_usb_dev_desc);
|
||||
return BUS_PROBE_DEFAULT;
|
||||
}
|
||||
|
||||
static int
|
||||
ehci_xls_attach(device_t self)
|
||||
{
|
||||
ehci_softc_t *sc = device_get_softc(self);
|
||||
device_t parent;
|
||||
device_t *neighbors;
|
||||
int err;
|
||||
int rid;
|
||||
int count;
|
||||
int res;
|
||||
|
||||
|
||||
sc->sc_bus.usbrev = USBREV_2_0;
|
||||
|
||||
rid = 0;
|
||||
sc->io_res = bus_alloc_resource(self, SYS_RES_MEMORY, &rid,
|
||||
0ul, ~0ul, 0x400, RF_ACTIVE);
|
||||
if (!sc->io_res) {
|
||||
device_printf(self, "Could not map memory\n");
|
||||
return ENXIO;
|
||||
}
|
||||
sc->iot = rman_get_bustag(sc->io_res);
|
||||
sc->ioh = rman_get_bushandle(sc->io_res);
|
||||
|
||||
rid = 0;
|
||||
sc->irq_res = bus_alloc_resource(self, SYS_RES_IRQ, &rid,
|
||||
39, 39, 1, RF_SHAREABLE | RF_ACTIVE);
|
||||
if (sc->irq_res == NULL) {
|
||||
device_printf(self, "Could not allocate irq\n");
|
||||
ehci_xls_detach(self);
|
||||
return ENXIO;
|
||||
}
|
||||
sc->sc_bus.bdev = device_add_child(self, "usb", -1);
|
||||
if (!sc->sc_bus.bdev) {
|
||||
device_printf(self, "Could not add USB device\n");
|
||||
ehci_xls_detach(self);
|
||||
return ENOMEM;
|
||||
}
|
||||
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
|
||||
|
||||
/* ehci_pci_match will never return NULL if ehci_pci_probe succeeded */
|
||||
device_set_desc(sc->sc_bus.bdev, xlr_usb_dev_desc);
|
||||
sprintf(sc->sc_vendor, xlr_vendor_desc);
|
||||
|
||||
err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
|
||||
(driver_intr_t *) ehci_intr, sc, &sc->ih);
|
||||
if (err) {
|
||||
device_printf(self, "Could not setup irq, %d\n", err);
|
||||
sc->ih = NULL;
|
||||
ehci_xls_detach(self);
|
||||
return ENXIO;
|
||||
}
|
||||
/*
|
||||
* Find companion controllers. According to the spec they always
|
||||
* have lower function numbers so they should be enumerated already.
|
||||
*/
|
||||
parent = device_get_parent(self);
|
||||
res = device_get_children(parent, &neighbors, &count);
|
||||
if (res != 0) {
|
||||
device_printf(self, "Error finding companion busses\n");
|
||||
ehci_xls_detach(self);
|
||||
return ENXIO;
|
||||
}
|
||||
sc->sc_ncomp = 0;
|
||||
|
||||
ehci_xls_takecontroller(self);
|
||||
err = ehci_init(sc);
|
||||
if (!err) {
|
||||
sc->sc_flags |= EHCI_SCFLG_DONEINIT;
|
||||
err = device_probe_and_attach(sc->sc_bus.bdev);
|
||||
}
|
||||
if (err) {
|
||||
device_printf(self, "USB init failed err=%d\n", err);
|
||||
ehci_xls_detach(self);
|
||||
return EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ehci_xls_detach(device_t self)
|
||||
{
|
||||
ehci_softc_t *sc = device_get_softc(self);
|
||||
|
||||
if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
|
||||
ehci_detach(sc, 0);
|
||||
sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
|
||||
}
|
||||
/*
|
||||
* disable interrupts that might have been switched on in ehci_init
|
||||
*/
|
||||
if (sc->iot && sc->ioh)
|
||||
bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0);
|
||||
|
||||
if (sc->irq_res && sc->ih) {
|
||||
int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
|
||||
|
||||
if (err)
|
||||
/* XXX or should we panic? */
|
||||
device_printf(self, "Could not tear down irq, %d\n",
|
||||
err);
|
||||
sc->ih = NULL;
|
||||
}
|
||||
if (sc->sc_bus.bdev) {
|
||||
device_delete_child(self, sc->sc_bus.bdev);
|
||||
sc->sc_bus.bdev = NULL;
|
||||
}
|
||||
if (sc->irq_res) {
|
||||
bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
|
||||
sc->irq_res = NULL;
|
||||
}
|
||||
if (sc->io_res) {
|
||||
bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM, sc->io_res);
|
||||
sc->io_res = NULL;
|
||||
sc->iot = 0;
|
||||
sc->ioh = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ehci_xls_takecontroller(device_t self)
|
||||
{
|
||||
//device_printf(self, "In func %s\n", __func__);
|
||||
}
|
||||
|
||||
static void
|
||||
ehci_xls_givecontroller(device_t self)
|
||||
{
|
||||
//device_printf(self, "In func %s\n", __func__);
|
||||
}
|
||||
|
||||
static device_method_t ehci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, ehci_xls_probe),
|
||||
DEVMETHOD(device_attach, ehci_xls_attach),
|
||||
DEVMETHOD(device_detach, ehci_xls_detach),
|
||||
DEVMETHOD(device_suspend, ehci_xls_suspend),
|
||||
DEVMETHOD(device_resume, ehci_xls_resume),
|
||||
DEVMETHOD(device_shutdown, ehci_xls_shutdown),
|
||||
|
||||
/* Bus interface */
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static driver_t ehci_driver = {
|
||||
"ehci",
|
||||
ehci_methods,
|
||||
sizeof(ehci_softc_t),
|
||||
};
|
||||
|
||||
static devclass_t ehci_devclass;
|
||||
|
||||
DRIVER_MODULE(ehci, iodi, ehci_driver, ehci_devclass, 0, 0);
|
||||
/* DRIVER_MODULE(ehci, cardbus, ehci_driver, ehci_devclass, 0, 0); */
|
Loading…
Reference in New Issue
Block a user