1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef ARCH_X86_TOPOLOGY_H
3#define ARCH_X86_TOPOLOGY_H
4
5struct topo_scan {
6	struct cpuinfo_x86	*c;
7	unsigned int		dom_shifts[TOPO_MAX_DOMAIN];
8	unsigned int		dom_ncpus[TOPO_MAX_DOMAIN];
9
10	/* Legacy CPUID[1]:EBX[23:16] number of logical processors */
11	unsigned int		ebx1_nproc_shift;
12
13	/* AMD specific node ID which cannot be mapped into APIC space. */
14	u16			amd_nodes_per_pkg;
15	u16			amd_node_id;
16};
17
18void cpu_init_topology(struct cpuinfo_x86 *c);
19void cpu_parse_topology(struct cpuinfo_x86 *c);
20void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
21		      unsigned int shift, unsigned int ncpus);
22bool cpu_parse_topology_ext(struct topo_scan *tscan);
23void cpu_parse_topology_amd(struct topo_scan *tscan);
24void cpu_topology_fixup_amd(struct topo_scan *tscan);
25
26static inline u32 topo_shift_apicid(u32 apicid, enum x86_topology_domains dom)
27{
28	if (dom == TOPO_SMT_DOMAIN)
29		return apicid;
30	return apicid >> x86_topo_system.dom_shifts[dom - 1];
31}
32
33static inline u32 topo_relative_domain_id(u32 apicid, enum x86_topology_domains dom)
34{
35	if (dom != TOPO_SMT_DOMAIN)
36		apicid >>= x86_topo_system.dom_shifts[dom - 1];
37	return apicid & (x86_topo_system.dom_size[dom] - 1);
38}
39
40static inline u32 topo_domain_mask(enum x86_topology_domains dom)
41{
42	return (1U << x86_topo_system.dom_shifts[dom]) - 1;
43}
44
45/*
46 * Update a domain level after the fact without propagating. Used to fixup
47 * broken CPUID enumerations.
48 */
49static inline void topology_update_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
50				       unsigned int shift, unsigned int ncpus)
51{
52	tscan->dom_shifts[dom] = shift;
53	tscan->dom_ncpus[dom] = ncpus;
54}
55
56#ifdef CONFIG_X86_LOCAL_APIC
57unsigned int topology_unit_count(u32 apicid, enum x86_topology_domains which_units,
58				 enum x86_topology_domains at_level);
59#else
60static inline unsigned int topology_unit_count(u32 apicid, enum x86_topology_domains which_units,
61					       enum x86_topology_domains at_level)
62{
63	return 1;
64}
65#endif
66
67#endif /* ARCH_X86_TOPOLOGY_H */
68