| /* 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(); |
| } |