1139825Simp/*-
225164Speter * ----------------------------------------------------------------------------
325164Speter * "THE BEER-WARE LICENSE" (Revision 42):
425164Speter * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
525164Speter * can do whatever you want with this stuff. If we meet some day, and you think
625164Speter * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
725164Speter * ----------------------------------------------------------------------------
825164Speter *
950477Speter * $FreeBSD$
1025164Speter */
1125164Speter
1276078Sjhb#ifndef _SYS_SMP_H_
1376078Sjhb#define _SYS_SMP_H_
1425164Speter
1555205Speter#ifdef _KERNEL
1625164Speter
1776078Sjhb#ifndef LOCORE
1825517Sfsmp
19222813Sattilio#include <sys/cpuset.h>
20222813Sattilio
21117005Sjeff/*
22117005Sjeff * Topology of a NUMA or HTT system.
23117005Sjeff *
24117005Sjeff * The top level topology is an array of pointers to groups.  Each group
25117005Sjeff * contains a bitmask of cpus in its group or subgroups.  It may also
26117005Sjeff * contain a pointer to an array of child groups.
27117005Sjeff *
28117005Sjeff * The bitmasks at non leaf groups may be used by consumers who support
29117005Sjeff * a smaller depth than the hardware provides.
30117005Sjeff *
31117005Sjeff * The topology may be omitted by systems where all CPUs are equal.
32117005Sjeff */
33117005Sjeff
34117005Sjeffstruct cpu_group {
35176734Sjeff	struct cpu_group *cg_parent;	/* Our parent group. */
36176734Sjeff	struct cpu_group *cg_child;	/* Optional children groups. */
37222813Sattilio	cpuset_t	cg_mask;	/* Mask of cpus in this group. */
38222200Sattilio	int32_t		cg_count;	/* Count of cpus in this group. */
39222200Sattilio	int16_t		cg_children;	/* Number of children groups. */
40176734Sjeff	int8_t		cg_level;	/* Shared cache level. */
41176734Sjeff	int8_t		cg_flags;	/* Traversal modifiers. */
42117005Sjeff};
43117005Sjeff
44215159Snwhitehorntypedef struct cpu_group *cpu_group_t;
45215159Snwhitehorn
46176734Sjeff/*
47176734Sjeff * Defines common resources for CPUs in the group.  The highest level
48176734Sjeff * resource should be used when multiple are shared.
49176734Sjeff */
50176734Sjeff#define	CG_SHARE_NONE	0
51176734Sjeff#define	CG_SHARE_L1	1
52176734Sjeff#define	CG_SHARE_L2	2
53176734Sjeff#define	CG_SHARE_L3	3
54117005Sjeff
55176734Sjeff/*
56176734Sjeff * Behavior modifiers for load balancing and affinity.
57176734Sjeff */
58176734Sjeff#define	CG_FLAG_HTT	0x01		/* Schedule the alternate core last. */
59191643Sjeff#define	CG_FLAG_SMT	0x02		/* New age htt, less crippled. */
60191643Sjeff#define	CG_FLAG_THREAD	(CG_FLAG_HTT | CG_FLAG_SMT)	/* Any threading. */
61176734Sjeff
62176734Sjeff/*
63176734Sjeff * Convenience routines for building topologies.
64176734Sjeff */
65215159Snwhitehorn#ifdef SMP
66176734Sjeffstruct cpu_group *smp_topo(void);
67176734Sjeffstruct cpu_group *smp_topo_none(void);
68176734Sjeffstruct cpu_group *smp_topo_1level(int l1share, int l1count, int l1flags);
69176734Sjeffstruct cpu_group *smp_topo_2level(int l2share, int l2count, int l1share,
70176734Sjeff    int l1count, int l1flags);
71176734Sjeffstruct cpu_group *smp_topo_find(struct cpu_group *top, int cpu);
72176734Sjeff
7376078Sjhbextern void (*cpustop_restartfunc)(void);
7476078Sjhbextern int smp_cpus;
75222813Sattilioextern volatile cpuset_t started_cpus;
76222813Sattilioextern volatile cpuset_t stopped_cpus;
77236772Siwasakiextern volatile cpuset_t suspended_cpus;
78222813Sattilioextern cpuset_t hlt_cpus_mask;
79222813Sattilioextern cpuset_t logical_cpus_mask;
80123125Sjhb#endif /* SMP */
81123125Sjhb
8291673Sjeffextern u_int mp_maxid;
83134689Sjulianextern int mp_maxcpus;
84123125Sjhbextern int mp_ncpus;
85123125Sjhbextern volatile int smp_started;
8627728Sfsmp
87222813Sattilioextern cpuset_t all_cpus;
88134591Sjulian
8927002Sfsmp/*
9080779Sbmilekic * Macro allowing us to determine whether a CPU is absent at any given
9180779Sbmilekic * time, thus permitting us to configure sparse maps of cpuid-dependent
9280779Sbmilekic * (per-CPU) structures.
9380779Sbmilekic */
94222813Sattilio#define	CPU_ABSENT(x_cpu)	(!CPU_ISSET(x_cpu, &all_cpus))
9580779Sbmilekic
96209050Sjhb/*
97209050Sjhb * Macros to iterate over non-absent CPUs.  CPU_FOREACH() takes an
98209050Sjhb * integer iterator and iterates over the available set of CPUs.
99209050Sjhb * CPU_FIRST() returns the id of the first non-absent CPU.  CPU_NEXT()
100209050Sjhb * returns the id of the next non-absent CPU.  It will wrap back to
101209050Sjhb * CPU_FIRST() once the end of the list is reached.  The iterators are
102209050Sjhb * currently implemented via inline functions.
103209050Sjhb */
104209050Sjhb#define	CPU_FOREACH(i)							\
105209050Sjhb	for ((i) = 0; (i) <= mp_maxid; (i)++)				\
106209050Sjhb		if (!CPU_ABSENT((i)))
107209050Sjhb
108209050Sjhbstatic __inline int
109209050Sjhbcpu_first(void)
110209050Sjhb{
111209050Sjhb	int i;
112209050Sjhb
113209050Sjhb	for (i = 0;; i++)
114209050Sjhb		if (!CPU_ABSENT(i))
115209050Sjhb			return (i);
116209050Sjhb}
117209050Sjhb
118209050Sjhbstatic __inline int
119209050Sjhbcpu_next(int i)
120209050Sjhb{
121209050Sjhb
122209050Sjhb	for (;;) {
123209050Sjhb		i++;
124209050Sjhb		if (i > mp_maxid)
125209050Sjhb			i = 0;
126209050Sjhb		if (!CPU_ABSENT(i))
127209050Sjhb			return (i);
128209050Sjhb	}
129209050Sjhb}
130209050Sjhb
131209050Sjhb#define	CPU_FIRST()	cpu_first()
132209050Sjhb#define	CPU_NEXT(i)	cpu_next((i))
133209050Sjhb
134123125Sjhb#ifdef SMP
13580779Sbmilekic/*
13676078Sjhb * Machine dependent functions used to initialize MP support.
13776078Sjhb *
13876078Sjhb * The cpu_mp_probe() should check to see if MP support is present and return
13976078Sjhb * zero if it is not or non-zero if it is.  If MP support is present, then
14076078Sjhb * cpu_mp_start() will be called so that MP can be enabled.  This function
14176078Sjhb * should do things such as startup secondary processors.  It should also
14276078Sjhb * setup mp_ncpus, all_cpus, and smp_cpus.  It should also ensure that
143265606Sscottl * smp_started is initialized at the appropriate time.
14476078Sjhb * Once cpu_mp_start() returns, machine independent MP startup code will be
14576078Sjhb * executed and a simple message will be output to the console.  Finally,
14676078Sjhb * cpu_mp_announce() will be called so that machine dependent messages about
14776078Sjhb * the MP support may be output to the console if desired.
148122947Sjhb *
149122947Sjhb * The cpu_setmaxid() function is called very early during the boot process
150122947Sjhb * so that the MD code may set mp_maxid to provide an upper bound on CPU IDs
151122947Sjhb * that other subsystems may use.  If a platform is not able to determine
152123126Sjhb * the exact maximum ID that early, then it may set mp_maxid to MAXCPU - 1.
15327002Sfsmp */
15496999Sjakestruct thread;
15596999Sjake
156176734Sjeffstruct cpu_group *cpu_topo(void);
15776078Sjhbvoid	cpu_mp_announce(void);
15876078Sjhbint	cpu_mp_probe(void);
159122947Sjhbvoid	cpu_mp_setmaxid(void);
16076078Sjhbvoid	cpu_mp_start(void);
16127002Sfsmp
16283366Sjulianvoid	forward_signal(struct thread *);
163222813Sattilioint	restart_cpus(cpuset_t);
164222813Sattilioint	stop_cpus(cpuset_t);
165222813Sattilioint	stop_cpus_hard(cpuset_t);
166235622Siwasaki#if defined(__amd64__) || defined(__i386__)
167222813Sattilioint	suspend_cpus(cpuset_t);
168255726Sgibbsint	resume_cpus(cpuset_t);
169189903Sjkim#endif
170243046Sjeff
17176078Sjhbvoid	smp_rendezvous_action(void);
172134416Sobrienextern	struct mtx smp_ipi_mtx;
173145727Sdwhite
174123125Sjhb#endif /* SMP */
175243046Sjeff
176243046Sjeffint	quiesce_all_cpus(const char *, int);
177243046Sjeffint	quiesce_cpus(cpuset_t, const char *, int);
178179230Sjbvoid	smp_no_rendevous_barrier(void *);
17976078Sjhbvoid	smp_rendezvous(void (*)(void *),
18076078Sjhb		       void (*)(void *),
18176078Sjhb		       void (*)(void *),
18276078Sjhb		       void *arg);
183222813Sattiliovoid	smp_rendezvous_cpus(cpuset_t,
184179230Sjb		       void (*)(void *),
185179230Sjb		       void (*)(void *),
186179230Sjb		       void (*)(void *),
187179230Sjb		       void *arg);
18827728Sfsmp#endif /* !LOCORE */
18955205Speter#endif /* _KERNEL */
19076078Sjhb#endif /* _SYS_SMP_H_ */
191