xref: /illumos-gate/usr/src/uts/sun4u/sys/opl_cfg.h (revision e98fafb9)
125cf1a30Sjl /*
225cf1a30Sjl  * CDDL HEADER START
325cf1a30Sjl  *
425cf1a30Sjl  * The contents of this file are subject to the terms of the
525cf1a30Sjl  * Common Development and Distribution License (the "License").
625cf1a30Sjl  * You may not use this file except in compliance with the License.
725cf1a30Sjl  *
825cf1a30Sjl  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
925cf1a30Sjl  * or http://www.opensolaris.org/os/licensing.
1025cf1a30Sjl  * See the License for the specific language governing permissions
1125cf1a30Sjl  * and limitations under the License.
1225cf1a30Sjl  *
1325cf1a30Sjl  * When distributing Covered Code, include this CDDL HEADER in each
1425cf1a30Sjl  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1525cf1a30Sjl  * If applicable, add the following below this CDDL HEADER, with the
1625cf1a30Sjl  * fields enclosed by brackets "[]" replaced with your own identifying
1725cf1a30Sjl  * information: Portions Copyright [yyyy] [name of copyright owner]
1825cf1a30Sjl  *
1925cf1a30Sjl  * CDDL HEADER END
2025cf1a30Sjl  */
2125cf1a30Sjl /*
22*e98fafb9Sjl  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2325cf1a30Sjl  * Use is subject to license terms.
2425cf1a30Sjl  */
2525cf1a30Sjl 
2625cf1a30Sjl #ifndef	_SYS_OPL_CFG_H
2725cf1a30Sjl #define	_SYS_OPL_CFG_H
2825cf1a30Sjl 
2925cf1a30Sjl #pragma ident	"%Z%%M%	%I%	%E% SMI"
3025cf1a30Sjl 
3125cf1a30Sjl #ifdef	__cplusplus
3225cf1a30Sjl extern "C" {
3325cf1a30Sjl #endif
3425cf1a30Sjl 
3525cf1a30Sjl /*
3625cf1a30Sjl  * Hardware Descriptor.
3725cf1a30Sjl  */
3825cf1a30Sjl 
3925cf1a30Sjl #include <sys/opl_hwdesc.h>
4025cf1a30Sjl 
4125cf1a30Sjl #define	OPL_PSB_MODE	0x0
4225cf1a30Sjl #define	OPL_XSB_MODE	0x1
4325cf1a30Sjl 
4425cf1a30Sjl #define	OPL_LSBID_MASK	0x1f
4525cf1a30Sjl 
4625cf1a30Sjl /*
4725cf1a30Sjl  * CPU device portid:
4825cf1a30Sjl  *
4925cf1a30Sjl  *	  1  0  0  0  0  0  0  0   0  0    0
5025cf1a30Sjl  *	  0  9  8  7  6  5  4  3   2  1    0
5125cf1a30Sjl  *      ---------------------------------------
5225cf1a30Sjl  *	| 1 |   LSB ID    | CHIP | CORE | CPU |
5325cf1a30Sjl  * 	---------------------------------------
5425cf1a30Sjl  */
5525cf1a30Sjl #define	OPL_CPUID_TO_LSB(devid)	((devid >> 5) & OPL_LSBID_MASK)
5625cf1a30Sjl #define	OPL_CPU_CHIP(devid)	((devid >> 3) & 0x3)
5725cf1a30Sjl #define	OPL_CORE(devid)		((devid >> 1) & 0x3)
5825cf1a30Sjl #define	OPL_CPU(devid)		((devid & 0x001))
5925cf1a30Sjl 
6025cf1a30Sjl #define	OPL_PORTID(board, chip)		((1 << 10) | (board << 5) | (chip << 3))
6125cf1a30Sjl 
6225cf1a30Sjl #define	OPL_CPUID(board, chip, core, cpu)				\
6325cf1a30Sjl 									\
6425cf1a30Sjl 	((board << 5) | (chip << 3) | (core << 1) | (cpu))
6525cf1a30Sjl 
6625cf1a30Sjl /*
6725cf1a30Sjl  * Dummy address space for a chip.
6825cf1a30Sjl  */
6925cf1a30Sjl #define	OPL_PROC_AS(board, chip)					\
7025cf1a30Sjl 									\
7125cf1a30Sjl 	((1ULL << 46) | ((uint64_t)board << 40) | (1ULL << 39) | 	\
7225cf1a30Sjl 		(1ULL << 33) | ((uint64_t)chip << 4))
7325cf1a30Sjl 
7425cf1a30Sjl /*
7525cf1a30Sjl  * pseudo-mc portid:
7625cf1a30Sjl  *
7725cf1a30Sjl  *	  1   0   0  0  0  0  0   0  0  0  0
7825cf1a30Sjl  *	  0   9   8  7  6  5  4   3  2  1  0
7925cf1a30Sjl  *      -------------------------------------
8025cf1a30Sjl  *	| 0 | 1 |     LSB ID    |    0      |
8125cf1a30Sjl  * 	-------------------------------------
8225cf1a30Sjl  */
8325cf1a30Sjl #define	OPL_LSB_TO_PSEUDOMC_PORTID(board)	((1 << 9) | (board << 4))
8425cf1a30Sjl 
8525cf1a30Sjl /*
8625cf1a30Sjl  * Dummy address space for a pseudo memory node
8725cf1a30Sjl  */
8825cf1a30Sjl #define	OPL_MC_AS(board)						\
8925cf1a30Sjl 									\
9025cf1a30Sjl 	((1ULL << 46) | ((uint64_t)board << 40) | (1ULL << 39) | 	\
9125cf1a30Sjl 		(1ULL << 33))
9225cf1a30Sjl 
9325cf1a30Sjl /*
9425cf1a30Sjl  * Defines used by the Jupiter bus-specific library (lfc_jupiter.so).
9525cf1a30Sjl  * This library gets loaded into the user-level fcode interpreter
9625cf1a30Sjl  * and provides bus-specific methods that are used by the Oberon
9725cf1a30Sjl  * and the CMU-channel fcode drivers.
9825cf1a30Sjl  */
9925cf1a30Sjl /*
10025cf1a30Sjl  *
10125cf1a30Sjl  * IO port id:
10225cf1a30Sjl  *
10325cf1a30Sjl  *	  1  0  0  0  0  0  0  0   0  0    0
10425cf1a30Sjl  *	  0  9  8  7  6  5  4  3   2  1    0
10525cf1a30Sjl  *      ---------------------------------------
10625cf1a30Sjl  *	| 0  0 |   LSB ID    | IO CHAN | LEAF |
10725cf1a30Sjl  * 	---------------------------------------
10825cf1a30Sjl  */
10925cf1a30Sjl #define	OPL_PORTID_MASK			0x7FF
11025cf1a30Sjl #define	OPL_IO_PORTID_TO_LSB(portid)	(((portid) >> 4) & OPL_LSBID_MASK)
11125cf1a30Sjl #define	OPL_PORTID_TO_CHANNEL(portid)	(((portid) >> 1) & 0x7)
11225cf1a30Sjl #define	OPL_PORTID_TO_LEAF(portid)	((portid) & 0x1)
11325cf1a30Sjl #define	OPL_IO_PORTID(lsb, ch, leaf)	\
11425cf1a30Sjl 	(((lsb & OPL_LSBID_MASK) << 4) | ((ch & 0x7) << 1) | (leaf & 0x1))
11525cf1a30Sjl 
11625cf1a30Sjl #define	OPL_ADDR_TO_LSB(hi)		(((hi) >> 8) & OPL_LSBID_MASK)
11725cf1a30Sjl #define	OPL_ADDR_TO_CHANNEL(hi)		(((hi) >> 5) & 0x7)
11825cf1a30Sjl #define	OPL_ADDR_TO_LEAF(hi, lo)	\
11925cf1a30Sjl 		(!(((hi) >> 7) & 0x1) && (((lo) >> 20) == 0x7))
12025cf1a30Sjl 
12125cf1a30Sjl #define	OPL_ADDR_HI(lsb, ch)		\
12225cf1a30Sjl 		((1 << 14) | ((lsb & OPL_LSBID_MASK) << 8) | ((ch & 0x7) << 5))
12325cf1a30Sjl 
12425cf1a30Sjl #define	OPL_CMU_CHANNEL	4
12525cf1a30Sjl #define	OPL_OBERON_CHANNEL(ch)	((ch >= 0) && (ch <= 3))
12625cf1a30Sjl #define	OPL_VALID_CHANNEL(ch)	((ch >= 0) && (ch <= 4))
12725cf1a30Sjl #define	OPL_VALID_LEAF(leaf)	((leaf == 0) || (leaf == 1))
12825cf1a30Sjl 
12925cf1a30Sjl #if defined(_KERNEL)
13025cf1a30Sjl 
13125cf1a30Sjl /*
13225cf1a30Sjl  * We store the pointers to the following device nodes in this structure:
13325cf1a30Sjl  *	"pseudo-mc"
13425cf1a30Sjl  *	"cmp"
13525cf1a30Sjl  *	"pci"
13625cf1a30Sjl  *
13725cf1a30Sjl  * These nodes represent the different branches we create in the device
13825cf1a30Sjl  * tree for each board during probe. We store them so that when a board
13925cf1a30Sjl  * is unprobed, we can easily locate the branches and destroy them.
14025cf1a30Sjl  */
14125cf1a30Sjl typedef struct {
14225cf1a30Sjl 	dev_info_t		*cfg_pseudo_mc;
14325cf1a30Sjl 	dev_info_t		*cfg_cpu_chips[HWD_CPU_CHIPS_PER_CMU];
14425cf1a30Sjl 	dev_info_t		*cfg_cmuch_leaf;
14525cf1a30Sjl 	fco_handle_t		cfg_cmuch_handle;
14625cf1a30Sjl 	char			*cfg_cmuch_probe_str;
14725cf1a30Sjl 	dev_info_t		*cfg_pcich_leaf[HWD_PCI_CHANNELS_PER_SB]
14825cf1a30Sjl 						[HWD_LEAVES_PER_PCI_CHANNEL];
14925cf1a30Sjl 	fco_handle_t		cfg_pcich_handle[HWD_PCI_CHANNELS_PER_SB]
15025cf1a30Sjl 						[HWD_LEAVES_PER_PCI_CHANNEL];
15125cf1a30Sjl 	char			*cfg_pcich_probe_str[HWD_PCI_CHANNELS_PER_SB]
15225cf1a30Sjl 						[HWD_LEAVES_PER_PCI_CHANNEL];
15325cf1a30Sjl 	void			*cfg_hwd;
15425cf1a30Sjl } opl_board_cfg_t;
15525cf1a30Sjl 
15625cf1a30Sjl /*
15725cf1a30Sjl  * Prototypes for the callback functions used in the DDI functions
15825cf1a30Sjl  * used to perform device tree operations.
15925cf1a30Sjl  *
16025cf1a30Sjl  * init functions are used to find device nodes that are created
16125cf1a30Sjl  * by Solaris during boot.
16225cf1a30Sjl  *
16325cf1a30Sjl  * create functions are used to initialize device nodes during DR.
16425cf1a30Sjl  */
16525cf1a30Sjl typedef int	(*opl_init_func_t)(dev_info_t *, char *, int);
16625cf1a30Sjl typedef int	(*opl_create_func_t)(dev_info_t *, void *, uint_t);
16725cf1a30Sjl 
16825cf1a30Sjl /*
16925cf1a30Sjl  * The following probe structure carries all the information required
17025cf1a30Sjl  * at various points during probe. This structure serves two purposes:
17125cf1a30Sjl  *
17225cf1a30Sjl  *	1. It allows us to streamline functions and have them accept just
17325cf1a30Sjl  *	   a single argument.
17425cf1a30Sjl  *
17525cf1a30Sjl  *	2. It allows us to pass information to the DDI callbacks. DDI
17625cf1a30Sjl  *	   callbacks are allowed only one argument. It also allows
17725cf1a30Sjl  *	   us to return information from those callbacks.
17825cf1a30Sjl  *
17925cf1a30Sjl  * The probe structure carries a snapshot of the hardware descriptor
18025cf1a30Sjl  * taken at the beginning of a probe.
18125cf1a30Sjl  */
18225cf1a30Sjl typedef struct {
18325cf1a30Sjl 	hwd_header_t		*pr_hdr;
18425cf1a30Sjl 	hwd_sb_status_t		*pr_sb_status;
18525cf1a30Sjl 	hwd_domain_info_t	*pr_dinfo;
18625cf1a30Sjl 	hwd_sb_t		*pr_sb;
18725cf1a30Sjl 
18825cf1a30Sjl 	int			pr_board;
18925cf1a30Sjl 	int			pr_cpu_chip;
19025cf1a30Sjl 	int			pr_core;
19125cf1a30Sjl 	int			pr_cpu;
19225cf1a30Sjl 	int			pr_channel;
19325cf1a30Sjl 	int			pr_channel_status;
19425cf1a30Sjl 	int			pr_leaf;
19525cf1a30Sjl 	int			pr_leaf_status;
19625cf1a30Sjl 
19725cf1a30Sjl 	opl_create_func_t	pr_create;
19825cf1a30Sjl 	dev_info_t		*pr_parent;
19925cf1a30Sjl 	dev_info_t		*pr_node;
20025cf1a30Sjl 	int			pr_hold;
201*e98fafb9Sjl 	unsigned		pr_cpu_impl;
20225cf1a30Sjl } opl_probe_t;
20325cf1a30Sjl 
20425cf1a30Sjl #define	OPL_STR_LEN	256
20525cf1a30Sjl 
20625cf1a30Sjl #define	OPL_HI(value)	((uint32_t)((uint64_t)(value) >> 32))
20725cf1a30Sjl #define	OPL_LO(value)	((uint32_t)(value))
20825cf1a30Sjl 
20925cf1a30Sjl typedef struct {
21025cf1a30Sjl 	uint32_t	addr_hi;
21125cf1a30Sjl 	uint32_t	addr_lo;
21225cf1a30Sjl } opl_addr_t;
21325cf1a30Sjl 
21425cf1a30Sjl typedef struct {
21525cf1a30Sjl 	uint32_t	rg_addr_hi;
21625cf1a30Sjl 	uint32_t	rg_addr_lo;
21725cf1a30Sjl 	uint32_t	rg_size_hi;
21825cf1a30Sjl 	uint32_t	rg_size_lo;
21925cf1a30Sjl } opl_range_t;
22025cf1a30Sjl 
22125cf1a30Sjl typedef struct {
22225cf1a30Sjl 	int		mc_bank;
22325cf1a30Sjl 	uint32_t	mc_hi;
22425cf1a30Sjl 	uint32_t	mc_lo;
22525cf1a30Sjl } opl_mc_addr_t;
22625cf1a30Sjl 
22725cf1a30Sjl /*
22825cf1a30Sjl  * Convenience macros for DDI property operations. The functions that
22925cf1a30Sjl  * DDI provides for getting and updating properties are not symmetric
23025cf1a30Sjl  * either in their names or in the number of arguments. These macros
23125cf1a30Sjl  * hide the gory details and provide a symmetric way to get and
23225cf1a30Sjl  * set properties.
23325cf1a30Sjl  */
23425cf1a30Sjl #define	opl_prop_get_string(dip, name, bufp, lenp)			\
23525cf1a30Sjl 	ddi_getlongprop(DDI_DEV_T_ANY, dip,				\
23625cf1a30Sjl 			DDI_PROP_DONTPASS, name, (caddr_t)bufp, lenp)
23725cf1a30Sjl 
23825cf1a30Sjl #define	opl_prop_get_int(dip, name, value, defvalue)			\
23925cf1a30Sjl (									\
24025cf1a30Sjl 	*(value) = ddi_getprop(DDI_DEV_T_ANY, dip,			\
24125cf1a30Sjl 			DDI_PROP_DONTPASS, name, defvalue),		\
24225cf1a30Sjl 	(*(value) == defvalue) ? DDI_PROP_NOT_FOUND : DDI_PROP_SUCCESS	\
24325cf1a30Sjl )
24425cf1a30Sjl 
24525cf1a30Sjl #define	opl_prop_get_int_array(dip, name, data, nelems)			\
24625cf1a30Sjl 	ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,			\
24725cf1a30Sjl 	DDI_PROP_DONTPASS, name, (int **)&data, (uint_t *)&nelems)
24825cf1a30Sjl 
24925cf1a30Sjl #define	OPL_GET_PROP(type, dip, name, value, arg)			\
25025cf1a30Sjl 	opl_prop_get_##type(dip, name, value, arg)
25125cf1a30Sjl 
25225cf1a30Sjl #define	OPL_GET_PROP_ARRAY(type, dip, name, values, nvalues)		\
25325cf1a30Sjl 	opl_prop_get_##type##_array(dip, name, values, nvalues)
25425cf1a30Sjl 
25525cf1a30Sjl #define	OPL_FREE_PROP(data)						\
25625cf1a30Sjl 	ddi_prop_free((void *)data)
25725cf1a30Sjl 
25825cf1a30Sjl #define	OPL_UPDATE_PROP_ERR(ret, name)					\
25925cf1a30Sjl 	if (ret != DDI_PROP_SUCCESS) {					\
26025cf1a30Sjl 		cmn_err(CE_WARN, "%s (%d): %s update property error (%d)",\
26125cf1a30Sjl 			__FILE__, __LINE__, name, ret);			\
26225cf1a30Sjl 		return (DDI_WALK_ERROR);				\
26325cf1a30Sjl 	}
26425cf1a30Sjl 
26525cf1a30Sjl #define	OPL_UPDATE_PROP(type, dip, name, value)				\
26625cf1a30Sjl 	ret = ndi_prop_update_##type(DDI_DEV_T_NONE, dip, name, value);	\
26725cf1a30Sjl 	OPL_UPDATE_PROP_ERR(ret, name)
26825cf1a30Sjl 
26925cf1a30Sjl 
27025cf1a30Sjl #define	OPL_UPDATE_PROP_ARRAY(type, dip, name, values, nvalues)		\
27125cf1a30Sjl 	ret = ndi_prop_update_##type##_array(DDI_DEV_T_NONE, dip,	\
27225cf1a30Sjl 						name, values, nvalues);	\
27325cf1a30Sjl 	OPL_UPDATE_PROP_ERR(ret, name)
27425cf1a30Sjl 
27525cf1a30Sjl /*
27625cf1a30Sjl  * Node names for the different nodes supported in OPL.
27725cf1a30Sjl  */
27825cf1a30Sjl #define	OPL_PSEUDO_MC_NODE	"pseudo-mc"
27925cf1a30Sjl #define	OPL_CPU_CHIP_NODE	"cmp"
28025cf1a30Sjl #define	OPL_CORE_NODE		"core"
28125cf1a30Sjl #define	OPL_CPU_NODE		"cpu"
28225cf1a30Sjl #define	OPL_PCI_LEAF_NODE	"pci"
28325cf1a30Sjl 
28425cf1a30Sjl typedef struct {
28525cf1a30Sjl 	char		*fc_service;
28625cf1a30Sjl 	fc_ops_t	*fc_op;
28725cf1a30Sjl } opl_fc_ops_t;
28825cf1a30Sjl 
28925cf1a30Sjl /*
29025cf1a30Sjl  * Functions used by drmach
29125cf1a30Sjl  */
292*e98fafb9Sjl extern int	opl_probe_sb(int, unsigned *);
29325cf1a30Sjl extern int	opl_unprobe_sb(int);
29425cf1a30Sjl extern int	opl_read_hwd(int, hwd_header_t **, hwd_sb_status_t **,
29525cf1a30Sjl 				hwd_domain_info_t **, hwd_sb_t **);
29625cf1a30Sjl extern void	opl_hold_devtree(void);
29725cf1a30Sjl extern void	opl_release_devtree(void);
29825cf1a30Sjl extern int	oplcfg_pa_swap(int from, int to);
29925cf1a30Sjl extern int	opl_init_cfg();
30025cf1a30Sjl 
30125cf1a30Sjl #endif /* _KERNEL */
30225cf1a30Sjl 
30325cf1a30Sjl #ifdef	__cplusplus
30425cf1a30Sjl }
30525cf1a30Sjl #endif
30625cf1a30Sjl 
30725cf1a30Sjl #endif	/* _SYS_OPL_CFG_H */
308