FreeBSD/sys/x86/x86/mp_x86.c
/*
 * Topology information is queried only on BSP, on which this
 * code runs and for which it can query CPUID information.
 * Then topology is extrapolated on all packages using an
 * assumption that APIC ID to hardware component ID mapping is
 * homogenious.
 * That doesn't necesserily imply that the topology is uniform.
 */
Topology information is queried only on BSP, on which this
code runs and for which it can query CPUID information.
Then topology is extrapolated on all packages using an
assumption that APIC ID to hardware component ID mapping is
homogenious.
That doesn't necesserily imply that the topology is uniform.
Topology information is queried only on BSP on which this code runs and for which it can query CPUID information . Then topology is extrapolated on all packages using an assumption that APIC ID to hardware component ID mapping is homogenious . That doesn ' t necesserily imply that the topology is uniform .
void
topo_probe(void)
{
	static int cpu_topo_probed = 0;
	struct x86_topo_layer {
		int type;
		int subtype;
		int id_shift;
	} topo_layers[MAX_CACHE_LEVELS + 3];
	struct topo_node *parent;
	struct topo_node *node;
	int layer;
	int nlayers;
	int node_id;
	int i;
	if (cpu_topo_probed)
		return;
	CPU_ZERO(&logical_cpus_mask);
	if (mp_ncpus <= 1)
		; 
	else if (cpu_vendor_id == CPU_VENDOR_AMD)
		topo_probe_amd();
	else if (cpu_vendor_id == CPU_VENDOR_INTEL)
		topo_probe_intel();
	KASSERT(pkg_id_shift >= core_id_shift,
	    ("bug in APIC topology discovery"));
	nlayers = 0;
	bzero(topo_layers, sizeof(topo_layers));
	topo_layers[nlayers].type = TOPO_TYPE_PKG;
	topo_layers[nlayers].id_shift = pkg_id_shift;
	if (bootverbose)
		printf("Package ID shift: %u\n", topo_layers[nlayers].id_shift);
	nlayers++;
	for (i = MAX_CACHE_LEVELS - 1; i >= 0; --i) {
		if (caches[i].present) {
			KASSERT(caches[i].id_shift <= pkg_id_shift,
				("bug in APIC topology discovery"));
			KASSERT(caches[i].id_shift >= core_id_shift,
				("bug in APIC topology discovery"));
			topo_layers[nlayers].type = TOPO_TYPE_CACHE;
			topo_layers[nlayers].subtype = i + 1;
			topo_layers[nlayers].id_shift = caches[i].id_shift;
			if (bootverbose)
				printf("L%u cache ID shift: %u\n",
				    topo_layers[nlayers].subtype,
				    topo_layers[nlayers].id_shift);
			nlayers++;
		}
	}
	if (pkg_id_shift > core_id_shift) {
		topo_layers[nlayers].type = TOPO_TYPE_CORE;
		topo_layers[nlayers].id_shift = core_id_shift;
		if (bootverbose)
			printf("Core ID shift: %u\n",
			    topo_layers[nlayers].id_shift);
		nlayers++;
	}
	topo_layers[nlayers].type = TOPO_TYPE_PU;
	topo_layers[nlayers].id_shift = 0;
	nlayers++;
	topo_init_root(&topo_root);
	for (i = 0; i <= MAX_APIC_ID; ++i) {
		if (!cpu_info[i].cpu_present)
			continue;
		parent = &topo_root;
		for (layer = 0; layer < nlayers; ++layer) {
			node_id = i >> topo_layers[layer].id_shift;
			parent = topo_add_node_by_hwid(parent, node_id,
			    topo_layers[layer].type,
			    topo_layers[layer].subtype);
		}
	}
	parent = &topo_root;
	for (layer = 0; layer < nlayers; ++layer) {
		node_id = boot_cpu_id >> topo_layers[layer].id_shift;
		node = topo_find_node_by_hwid(parent, node_id,
		    topo_layers[layer].type,
		    topo_layers[layer].subtype);
		topo_promote_child(node);
		parent = node;
	}
	cpu_topo_probed = 1;
}
void topo_probe ( void ) { static int cpu_topo_probed = 0 ; struct x86_topo_layer { int type ; int subtype ; int id_shift ; } topo_layers [ MAX_CACHE_LEVELS + 3 ] ; struct topo_node * parent ; struct topo_node * node ; int layer ; int nlayers ; int node_id ; int i ; if ( cpu_topo_probed ) return ; CPU_ZERO ( & logical_cpus_mask ) ; if ( mp_ncpus <= 1 ) ; else if ( cpu_vendor_id == CPU_VENDOR_AMD ) topo_probe_amd ( ) ; else if ( cpu_vendor_id == CPU_VENDOR_INTEL ) topo_probe_intel ( ) ; KASSERT ( pkg_id_shift >= core_id_shift , ( " " ) ) ; nlayers = 0 ; bzero ( topo_layers , sizeof ( topo_layers ) ) ; topo_layers [ nlayers ] . type = TOPO_TYPE_PKG ; topo_layers [ nlayers ] . id_shift = pkg_id_shift ; if ( bootverbose ) printf ( " \n " , topo_layers [ nlayers ] . id_shift ) ; nlayers ++ ; for ( i = MAX_CACHE_LEVELS - 1 ; i >= 0 ; -- i ) { if ( caches [ i ] . present ) { KASSERT ( caches [ i ] . id_shift <= pkg_id_shift , ( " " ) ) ; KASSERT ( caches [ i ] . id_shift >= core_id_shift , ( " " ) ) ; topo_layers [ nlayers ] . type = TOPO_TYPE_CACHE ; topo_layers [ nlayers ] . subtype = i + 1 ; topo_layers [ nlayers ] . id_shift = caches [ i ] . id_shift ; if ( bootverbose ) printf ( " \n " , topo_layers [ nlayers ] . subtype , topo_layers [ nlayers ] . id_shift ) ; nlayers ++ ; } } if ( pkg_id_shift > core_id_shift ) { topo_layers [ nlayers ] . type = TOPO_TYPE_CORE ; topo_layers [ nlayers ] . id_shift = core_id_shift ; if ( bootverbose ) printf ( " \n " , topo_layers [ nlayers ] . id_shift ) ; nlayers ++ ; } topo_layers [ nlayers ] . type = TOPO_TYPE_PU ; topo_layers [ nlayers ] . id_shift = 0 ; nlayers ++ ; topo_init_root ( & topo_root ) ; for ( i = 0 ; i <= MAX_APIC_ID ; ++ i ) { if ( ! cpu_info [ i ] . cpu_present ) continue ; parent = & topo_root ; for ( layer = 0 ; layer < nlayers ; ++ layer ) { node_id = i >> topo_layers [ layer ] . id_shift ; parent = topo_add_node_by_hwid ( parent , node_id , topo_layers [ layer ] . type , topo_layers [ layer ] . subtype ) ; } } parent = & topo_root ; for ( layer = 0 ; layer < nlayers ; ++ layer ) { node_id = boot_cpu_id >> topo_layers [ layer ] . id_shift ; node = topo_find_node_by_hwid ( parent , node_id , topo_layers [ layer ] . type , topo_layers [ layer ] . subtype ) ; topo_promote_child ( node ) ; parent = node ; } cpu_topo_probed = 1 ; }
Topology information is queried only on BSP, on which this
 code runs and for which it can query CPUID information.
Topology information is queried only on BSP on which this code runs and for which it can query CPUID information .
/* nothing */ /*
	 * Consider all caches to be within a package/chip
	 * and "in front" of all sub-components like
	 * cores and hardware threads.
	 */