summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/chip.h
blob: 226efb74cd861ebc9cc55642b96527933cdad5f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_CHIP_H
#define	_CHIP_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

/*
 * generic kernel CMT processor support
 */

#ifdef	__cplusplus
extern "C" {
#endif

#if (defined(_KERNEL) || defined(_KMEMUSER))
#include <sys/cpuvar.h>
#include <sys/processor.h>
#include <sys/bitmap.h>
#include <sys/atomic.h>
#include <sys/types.h>

/*
 * Chip types
 */
typedef enum chip_type {
	CHIP_DEFAULT,			/* Default, non CMT processor */
	CHIP_SMT,			/* SMT, single core */
	CHIP_CMP_SPLIT_CACHE,		/* CMP with split caches */
	CHIP_CMP_SHARED_CACHE,		/* CMP with shared caches */
	CHIP_NUM_TYPES
} chip_type_t;


/*
 * Balancing is possible if multiple chips exist in the lgroup
 * but only necessary if the chip has multiple online logical CPUs
 */
#define	CHIP_SHOULD_BALANCE(chp)		\
	(((chp)->chip_ncpu > 1) && ((chp)->chip_next_lgrp != (chp)))

/*
 * Platform's definition of a chip's properties
 */
typedef struct	chip_def {
	chip_type_t		chipd_type;
	int			chipd_rechoose_adj;
} chip_def_t;

/*
 * Per chip kstats
 */
typedef enum chip_stat_types {
	CHIP_ID,		/* chip "id" */
	CHIP_NCPUS,		/* number of active cpus */
	CHIP_NRUNNING,		/* number of running threads on chip */
	CHIP_RECHOOSE,		/* chip's rechoose_interval */
	CHIP_NUM_STATS		/* always last */
} chip_stat_t;

#define	CHIP_KSTAT_NAMES		\
static char *chip_kstat_names[] = {	\
					\
	"chip_id",			\
	"logical_cpus",			\
	"chip_nrunning",       		\
	"chip_rechoose_interval",	\
}

/*
 * Physical processor (chip) structure.
 */
typedef struct chip {
	chipid_t	chip_id;		/* chip's "id" */
	chipid_t	chip_seqid;		/* sequential id */
	struct chip	*chip_prev;		/* previous chip on list */
	struct chip	*chip_next;		/* next chip on list */
	struct chip	*chip_prev_lgrp;	/* prev chip in lgroup */
	struct chip	*chip_next_lgrp;	/* next chip in lgroup */
	chip_type_t	chip_type;		/* type of chip */
	uint16_t	chip_ncpu;		/* number of active cpus */
	uint16_t	chip_ref;		/* chip's reference count */
	struct cpu	*chip_cpus;		/* per chip cpu list */
	struct lgrp	*chip_lgrp;		/* chip lives in this lgroup */
	int		chip_rechoose_adj;	/* chip specific adjustment */

	/*
	 * chip kstats
	 */
	kstat_t			*chip_kstat;
	kmutex_t		chip_kstat_mutex;
	struct kstat_named	chip_kstat_data[CHIP_NUM_STATS];

	struct chip	*chip_balance;		/* chip to balance against */
	uint32_t	chip_nrunning;		/* # of running threads */
} chip_t;

/*
 * Change the number of running threads on the chip
 */
#define	CHIP_NRUNNING(chp, n) {						\
	atomic_add_32(&((chp)->chip_nrunning), (n));			\
}

/*
 * True if this CPU is active on the chip
 */
#define	CHIP_CPU_ACTIVE(cp)	((cp)->cpu_next_chip != NULL)

/*
 * Sets of chips
 * The "id" used here should be a chip's sequential id.
 * (chip_seqid)
 */
#if defined(_MACHDEP)

#define	CHIP_MAX_CHIPS	NCPU
#define	CHIP_SET_WORDS	BT_BITOUL(CHIP_MAX_CHIPS)

typedef struct chip_set {
	ulong_t csb[CHIP_SET_WORDS];
} chip_set_t;

extern	int	chip_set_isnull(chip_set_t *);

#define	CHIP_SET_ISNULL(set)		chip_set_isnull(&(set))
#define	CHIP_SET_TEST(set, id)		BT_TEST((set).csb, id)
#define	CHIP_SET_REMOVE(set, id)	BT_CLEAR((set).csb, id)
#define	CHIP_SET_ADD(set, id)		BT_SET((set).csb, id)

#define	CHIP_SET_ZERO(set) {				\
	int	_i;					\
	for (_i = 0; _i < CHIP_SET_WORDS; _i++)		\
		(set).csb[_i] = 0;			\
}

#define	CHIP_IN_CPUPART(chp, cp)			\
	(CHIP_SET_TEST((cp)->cp_chipset, (chp)->chip_seqid))

#endif	/* _MACHDEP */

/*
 * Common kernel chip operations
 */
void		chip_cpu_init(cpu_t *);
void		chip_cpu_fini(cpu_t *);
void		chip_cpu_assign(cpu_t *);
void		chip_cpu_unassign(cpu_t *);
void		chip_cpu_startup(cpu_t *);
void		chip_bootstrap_cpu(cpu_t *);

void		chip_cpu_move_part(cpu_t *, struct cpupart *,
			struct cpupart *);

void		chip_kstat_create(chip_t *);

/*
 * Platform chip operations
 */
chipid_t	chip_plat_get_chipid(cpu_t *);
#ifdef	sun4v
id_t		chip_plat_get_pipeid(cpu_t *);
#endif /* sun4v */

void		chip_plat_define_chip(cpu_t *, chip_def_t *);
int		chip_plat_get_clogid(cpu_t *);

#endif	/* !_KERNEL && !_KMEMUSER */

#ifdef	__cplusplus
}
#endif

#endif /* _CHIP_H */