| /* Copyright (c) 2015 The Regents of the University of California | 
 |  * Kevin Klues <klueska@cs.berkeley.edu> | 
 |  * See LICENSE for details. */ | 
 |  | 
 | #pragma once | 
 |  | 
 | #include <ros/common.h> | 
 | #include <arch/apic.h> | 
 | #include <arch/x86.h> | 
 |  | 
 | struct core_info { | 
 | 	int numa_id; | 
 | 	int socket_id; | 
 | 	int cpu_id; | 
 | 	int core_id; | 
 | 	int raw_socket_id; | 
 | 	int apic_id; | 
 | }; | 
 |  | 
 | struct topology_info { | 
 | 	int num_cores; | 
 | 	int num_cpus; | 
 | 	int num_sockets; | 
 | 	int num_numa; | 
 | 	int cores_per_cpu; | 
 | 	int cores_per_socket; | 
 | 	int cores_per_numa; | 
 | 	int cpus_per_socket; | 
 | 	int cpus_per_numa; | 
 | 	int sockets_per_numa; | 
 | 	int max_apic_id; | 
 | 	struct core_info *core_list; | 
 | }; | 
 |  | 
 | extern struct topology_info cpu_topology_info; | 
 | extern int *os_coreid_lookup; | 
 | #define num_cores (cpu_topology_info.num_cores) | 
 |  | 
 | void topology_init(); | 
 | void print_cpu_topology(); | 
 |  | 
 | static inline int get_hw_coreid(uint32_t coreid) | 
 | { | 
 | 	return cpu_topology_info.core_list[coreid].apic_id; | 
 | } | 
 |  | 
 | static inline int hw_core_id(void) | 
 | { | 
 | 	return lapic_get_id(); | 
 | } | 
 |  | 
 | static inline int get_os_coreid(int hw_coreid) | 
 | { | 
 | 	return os_coreid_lookup[hw_coreid]; | 
 | } | 
 |  | 
 | static inline int numa_id(void) | 
 | { | 
 | 	int os_coreid = os_coreid_lookup[lapic_get_id()]; | 
 |  | 
 | 	return cpu_topology_info.core_list[os_coreid].numa_id; | 
 | } | 
 |  | 
 | static inline int core_id(void) | 
 | { | 
 | 	int coreid; | 
 | 	/* assuming we're right after stacktop.  gs base is the pcpui struct, | 
 | 	 * but we don't have access to the pcpui struct or to the extern | 
 | 	 * per_cpu_info here, due to include loops. */ | 
 | 	asm volatile ("movl %%gs:8, %0" : "=r"(coreid)); | 
 | 	return coreid; | 
 | } | 
 |  | 
 | /* Tracks whether it is safe to execute core_id() or not. */ | 
 | static inline int core_id_early(void) | 
 | { | 
 | 	extern bool core_id_ready; | 
 |  | 
 | 	if (!core_id_ready) | 
 | 		return 0; | 
 | 	return core_id(); | 
 | } |