From 1bc7045fdfb85e6151d01c73669be19627c4783b Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Mon, 16 Dec 2013 03:58:43 +0100 Subject: [PATCH] kernel, libroot: Introduce new API for obtaining system info --- headers/os/kernel/OS.h | 358 +++--------- headers/private/kernel/arch/system_info.h | 2 +- headers/private/kernel/ksystem_info.h | 6 +- headers/private/shared/cpu_type.h | 527 +++++++++--------- headers/private/system/syscalls.h | 8 +- headers/private/system/system_info.h | 4 + src/apps/aboutsystem/AboutSystem.cpp | 35 +- src/apps/activitymonitor/DataSource.cpp | 6 +- src/apps/activitymonitor/SystemInfo.cpp | 3 + src/apps/activitymonitor/SystemInfo.h | 3 + .../controllers/DebugReportGenerator.cpp | 34 +- src/apps/diskprobe/TypeEditors.cpp | 2 +- src/apps/packageinstaller/PackageInfo.cpp | 33 +- src/apps/processcontroller/MemoryBarMenu.cpp | 4 +- src/apps/processcontroller/MemoryBarMenu.h | 2 +- .../processcontroller/ProcessController.cpp | 28 +- .../processcontroller/ProcessController.h | 2 +- .../processcontroller/TeamBarMenuItem.cpp | 5 +- src/apps/pulse/DeskbarPulseView.cpp | 3 +- src/apps/pulse/MiniPulseView.cpp | 5 +- src/apps/pulse/NormalPulseView.cpp | 43 +- src/apps/pulse/PulseApp.cpp | 4 +- src/apps/pulse/PulseApp.h | 2 +- src/apps/pulse/PulseView.cpp | 14 +- src/bin/Jamfile | 2 +- src/bin/coreutils/src/uname.c | 24 +- src/bin/sysinfo.cpp | 114 ++-- src/kits/tracker/TaskLoop.cpp | 10 +- src/servers/app/drawing/Painter/Painter.cpp | 2 +- .../kernel/arch/x86/arch_system_info.cpp | 130 ++--- src/system/kernel/system_info.cpp | 164 +++++- src/system/libroot/os/Jamfile | 2 +- src/system/libroot/os/system_info.c | 59 -- src/system/libroot/os/system_info.cpp | 242 ++++++++ src/system/libroot/posix/sys/uname.c | 33 +- 35 files changed, 1107 insertions(+), 808 deletions(-) delete mode 100644 src/system/libroot/os/system_info.c create mode 100644 src/system/libroot/os/system_info.cpp diff --git a/headers/os/kernel/OS.h b/headers/os/kernel/OS.h index 2ba449ce09..d6199a3d6a 100644 --- a/headers/os/kernel/OS.h +++ b/headers/os/kernel/OS.h @@ -420,220 +420,108 @@ extern void ktrace_vprintf(const char *format, va_list args); /* System information */ -typedef enum cpu_types { - /* TODO: add latest models */ +typedef struct { + bigtime_t active_time; /* usec of doing useful work since boot */ + int32 load; + bool enabled; +} cpu_info; - /* Motorola/IBM */ - B_CPU_PPC_UNKNOWN = 0, - B_CPU_PPC_601 = 1, - B_CPU_PPC_602 = 7, - B_CPU_PPC_603 = 2, - B_CPU_PPC_603e = 3, - B_CPU_PPC_603ev = 8, - B_CPU_PPC_604 = 4, - B_CPU_PPC_604e = 5, - B_CPU_PPC_604ev = 9, - B_CPU_PPC_620 = 10, - B_CPU_PPC_750 = 6, - B_CPU_PPC_686 = 13, - B_CPU_PPC_860 = 25, - B_CPU_PPC_7400 = 26, - B_CPU_PPC_7410 = 27, - B_CPU_PPC_7447A = 28, - B_CPU_PPC_7448 = 29, - B_CPU_PPC_7450 = 30, - B_CPU_PPC_7455 = 31, - B_CPU_PPC_7457 = 32, - B_CPU_PPC_8240 = 33, - B_CPU_PPC_8245 = 34, +typedef struct { + bigtime_t boot_time; /* time of boot (usecs since 1/1/1970) */ - B_CPU_PPC_IBM_401A1 = 35, - B_CPU_PPC_IBM_401B2 = 36, - B_CPU_PPC_IBM_401C2 = 37, - B_CPU_PPC_IBM_401D2 = 38, - B_CPU_PPC_IBM_401E2 = 39, - B_CPU_PPC_IBM_401F2 = 40, - B_CPU_PPC_IBM_401G2 = 41, - B_CPU_PPC_IBM_403 = 42, - B_CPU_PPC_IBM_405GP = 43, - B_CPU_PPC_IBM_405L = 44, - B_CPU_PPC_IBM_750FX = 45, - B_CPU_PPC_IBM_POWER3 = 46, + uint32 cpu_count; /* number of cpus */ - /* Intel */ + uint64 max_pages; /* total # of accessible pages */ + uint64 used_pages; /* # of accessible pages in use */ + uint64 free_pages; + uint64 reserved_pages; + uint64 cached_pages; + uint64 block_cache_pages; + uint64 ignored_pages; /* # of ignored/inaccessible pages */ - /* Updated according to Intel(R) Processor Identification and - * the CPUID instruction (Table 4) - * AP-485 Intel - 24161832.pdf - */ - B_CPU_INTEL_x86 = 0x1000, - B_CPU_INTEL_PENTIUM = 0x1051, - B_CPU_INTEL_PENTIUM75, - B_CPU_INTEL_PENTIUM_486_OVERDRIVE, - B_CPU_INTEL_PENTIUM_MMX, - B_CPU_INTEL_PENTIUM_MMX_MODEL_4 = B_CPU_INTEL_PENTIUM_MMX, - B_CPU_INTEL_PENTIUM_MMX_MODEL_8 = 0x1058, - B_CPU_INTEL_PENTIUM75_486_OVERDRIVE, - B_CPU_INTEL_PENTIUM_PRO = 0x1061, - B_CPU_INTEL_PENTIUM_II = 0x1063, - B_CPU_INTEL_PENTIUM_II_MODEL_3 = 0x1063, - B_CPU_INTEL_PENTIUM_II_MODEL_5 = 0x1065, - B_CPU_INTEL_CELERON = 0x1066, - B_CPU_INTEL_CELERON_MODEL_22 = 0x11066, - B_CPU_INTEL_PENTIUM_III = 0x1067, - B_CPU_INTEL_PENTIUM_III_MODEL_8 = 0x1068, - B_CPU_INTEL_PENTIUM_M = 0x1069, - B_CPU_INTEL_PENTIUM_III_XEON = 0x106a, - B_CPU_INTEL_PENTIUM_III_MODEL_11 = 0x106b, - B_CPU_INTEL_ATOM = 0x1106c, - B_CPU_INTEL_PENTIUM_M_MODEL_13 = 0x106d, /* Dothan */ - B_CPU_INTEL_PENTIUM_CORE, - B_CPU_INTEL_PENTIUM_CORE_2, - B_CPU_INTEL_PENTIUM_CORE_2_45_NM = 0x11067, /* Core 2 on 45 nm - (Core 2 Extreme, - Xeon model 23 or - Core 2 Duo/Quad) */ - B_CPU_INTEL_PENTIUM_CORE_I5_M430 = 0x21065, /* Core i5 M 430 @ 2.27 */ - B_CPU_INTEL_PENTIUM_CORE_I7 = 0x1106a, /* Core i7 920 @ 2.6(6) */ - B_CPU_INTEL_PENTIUM_CORE_I7_Q720 = 0x1106e, /* Core i7 Q720 @ 1.6 */ - B_CPU_INTEL_PENTIUM_IV = 0x10f0, - B_CPU_INTEL_PENTIUM_IV_MODEL_1, - B_CPU_INTEL_PENTIUM_IV_MODEL_2, - B_CPU_INTEL_PENTIUM_IV_MODEL_3, - B_CPU_INTEL_PENTIUM_IV_MODEL_4, + uint64 max_swap_pages; + uint64 used_swap_pages; - /* AMD */ + uint32 page_faults; /* # of page faults */ - // AMD Processor Recognition Application Note - B_CPU_AMD_x86 = 0x1100, + uint32 max_sems; + uint32 used_sems; - // Family 5h - B_CPU_AMD_K5_MODEL_0 = 0x1150, - B_CPU_AMD_K5_MODEL_1 = 0x1151, - B_CPU_AMD_K5_MODEL_2 = 0x1152, - B_CPU_AMD_K5_MODEL_3 = 0x1153, - B_CPU_AMD_K6_MODEL_6 = 0x1156, - B_CPU_AMD_K6_MODEL_7 = 0x1157, - B_CPU_AMD_K6_MODEL_8 = 0x1158, - B_CPU_AMD_K6_2 = 0x1158, - B_CPU_AMD_K6_MODEL_9 = 0x1159, - B_CPU_AMD_K6_III = 0x1159, - B_CPU_AMD_K6_III_MODEL_13 = 0x115d, + uint32 max_ports; + uint32 used_ports; - B_CPU_AMD_GEODE_LX = 0x115a, + uint32 max_threads; + uint32 used_threads; - // Family 6h - B_CPU_AMD_ATHLON_MODEL_1 = 0x1161, - B_CPU_AMD_ATHLON_MODEL_2 = 0x1162, + uint32 max_teams; + uint32 used_teams; - B_CPU_AMD_DURON = 0x1163, + char kernel_name[B_FILE_NAME_LENGTH]; + char kernel_build_date[B_OS_NAME_LENGTH]; + char kernel_build_time[B_OS_NAME_LENGTH]; - B_CPU_AMD_ATHLON_THUNDERBIRD = 0x1164, - B_CPU_AMD_ATHLON_XP_MODEL_6 = 0x1166, - B_CPU_AMD_ATHLON_XP_MODEL_7 = 0x1167, - B_CPU_AMD_ATHLON_XP_MODEL_8 = 0x1168, - B_CPU_AMD_ATHLON_XP_MODEL_10 = 0x116a, /* Barton */ + int64 kernel_version; + uint32 abi; /* the system API */ +} system_info; - // Family fh - B_CPU_AMD_ATHLON_64_MODEL_3 = 0x11f3, - B_CPU_AMD_ATHLON_64_MODEL_4 = 0x11f4, - B_CPU_AMD_ATHLON_64_MODEL_7 = 0x11f7, - B_CPU_AMD_ATHLON_64_MODEL_8 = 0x11f8, - B_CPU_AMD_ATHLON_64_MODEL_11 = 0x11fb, - B_CPU_AMD_ATHLON_64_MODEL_12 = 0x11fc, - B_CPU_AMD_ATHLON_64_MODEL_14 = 0x11fe, - B_CPU_AMD_ATHLON_64_MODEL_15 = 0x11ff, - B_CPU_AMD_ATHLON_64_MODEL_20 = 0x111f4, - B_CPU_AMD_ATHLON_64_MODEL_23 = 0x111f7, - B_CPU_AMD_ATHLON_64_MODEL_24 = 0x111f8, - B_CPU_AMD_ATHLON_64_MODEL_27 = 0x111fb, - B_CPU_AMD_ATHLON_64_MODEL_28 = 0x111fc, - B_CPU_AMD_ATHLON_64_MODEL_31 = 0x111ff, - B_CPU_AMD_ATHLON_64_MODEL_35 = 0x211f3, - B_CPU_AMD_ATHLON_64_MODEL_43 = 0x211fb, - B_CPU_AMD_ATHLON_64_MODEL_44 = 0x211fc, - B_CPU_AMD_ATHLON_64_MODEL_47 = 0x211ff, - B_CPU_AMD_ATHLON_64_MODEL_63 = 0x311ff, - B_CPU_AMD_ATHLON_64_MODEL_79 = 0x411ff, - B_CPU_AMD_ATHLON_64_MODEL_95 = 0x511ff, - B_CPU_AMD_ATHLON_64_MODEL_127 = 0x711ff, +enum topology_level_type { + B_TOPOLOGY_UNKNOWN, + B_TOPOLOGY_ROOT, + B_TOPOLOGY_SMT, + B_TOPOLOGY_CORE, + B_TOPOLOGY_PACKAGE +}; - B_CPU_AMD_OPTERON_MODEL_5 = 0x11f5, - B_CPU_AMD_OPTERON_MODEL_21 = 0x111f5, - B_CPU_AMD_OPTERON_MODEL_33 = 0x211f1, - B_CPU_AMD_OPTERON_MODEL_37 = 0x211f5, - B_CPU_AMD_OPTERON_MODEL_39 = 0x211f7, - - B_CPU_AMD_TURION_64_MODEL_36 = 0x211f4, - B_CPU_AMD_TURION_64_MODEL_76 = 0x411fc, - B_CPU_AMD_TURION_64_MODEL_104 = 0x611f8, - - // Family 10h - B_CPU_AMD_PHENOM_MODEL_2 = 0x1011f2, - B_CPU_AMD_PHENOM_II_MODEL_4 = 0x1011f4, - B_CPU_AMD_PHENOM_II_MODEL_5 = 0x1011f5, - B_CPU_AMD_PHENOM_II_MODEL_6 = 0x1011f6, - B_CPU_AMD_PHENOM_II_MODEL_10 = 0x1011fa, - - // Family 12h - B_CPU_AMD_A_SERIES = 0x3011f1, - - // Family 14h - B_CPU_AMD_C_SERIES = 0x5011f1, - B_CPU_AMD_E_SERIES = 0x5011f2, - - // Family 15h - B_CPU_AMD_FX_SERIES_MODEL_1 = 0x6011f1, /* Bulldozer */ - B_CPU_AMD_FX_SERIES_MODEL_2 = 0x6011f2, - - /* VIA/Cyrix */ - B_CPU_CYRIX_x86 = 0x1200, - B_CPU_VIA_CYRIX_x86 = 0x1200, - B_CPU_CYRIX_GXm = 0x1254, - B_CPU_CYRIX_6x86MX = 0x1260, - - /* VIA/IDT */ - B_CPU_IDT_x86 = 0x1300, - B_CPU_VIA_IDT_x86 = 0x1300, - B_CPU_IDT_WINCHIP_C6 = 0x1354, - B_CPU_IDT_WINCHIP_2 = 0x1358, - B_CPU_IDT_WINCHIP_3, - B_CPU_VIA_C3_SAMUEL = 0x1366, - B_CPU_VIA_C3_SAMUEL_2 = 0x1367, - B_CPU_VIA_C3_EZRA_T = 0x1368, - B_CPU_VIA_C3_NEHEMIAH = 0x1369, - B_CPU_VIA_C7_ESTHER = 0x136a, - B_CPU_VIA_C7_ESTHER_2 = 0x136d, - B_CPU_VIA_NANO_ISAIAH = 0x136f, - - /* Transmeta */ - B_CPU_TRANSMETA_x86 = 0x1600, - B_CPU_TRANSMETA_CRUSOE = 0x1654, - B_CPU_TRANSMETA_EFFICEON = 0x16f2, - B_CPU_TRANSMETA_EFFICEON_2 = 0x16f3, - - /* Rise */ - B_CPU_RISE_x86 = 0x1400, - B_CPU_RISE_mP6 = 0x1450, - - /* National Semiconductor */ - B_CPU_NATIONAL_x86 = 0x1500, - B_CPU_NATIONAL_GEODE_GX1 = 0x1554, - B_CPU_NATIONAL_GEODE_GX2, - - /* For compatibility */ - B_CPU_AMD_29K = 14, +enum cpu_platform { + B_CPU_UNKNOWN, B_CPU_x86, - B_CPU_MC6502, - B_CPU_Z80, - B_CPU_ALPHA, - B_CPU_MIPS, - B_CPU_HPPA, - B_CPU_M68K, - B_CPU_ARM, - B_CPU_SH, - B_CPU_SPARC -} cpu_type; + B_CPU_x86_64 +}; + +enum cpu_vendor { + B_CPU_VENDOR_UNKNOWN, + B_CPU_VENDOR_AMD, + B_CPU_VENDOR_CYRIX, + B_CPU_VENDOR_IDT, + B_CPU_VENDOR_INTEL, + B_CPU_VENDOR_NATIONAL_SEMICONDUCTOR, + B_CPU_VENDOR_RISE, + B_CPU_VENDOR_TRANSMETA, + B_CPU_VENDOR_VIA +}; + +typedef struct { + enum cpu_platform platform; +} cpu_topology_root_info; + +typedef struct { + enum cpu_vendor vendor; + uint32 cache_line_size; +} cpu_topology_package_info; + +typedef struct { + uint32 model; + uint64 default_frequency; +} cpu_topology_core_info; + +typedef struct { + uint32 id; + enum topology_level_type type; + uint32 level; + + union { + cpu_topology_root_info root; + cpu_topology_package_info package; + cpu_topology_core_info core; + } data; +} cpu_topology_node_info; + + +extern status_t get_system_info(system_info* info); +extern status_t get_cpu_info(uint32 firstCPU, uint32 cpuCount, + cpu_info* info); +extern status_t get_cpu_topology_info(cpu_topology_node_info* topologyInfos, + uint32* topologyInfoCount); #define B_CPU_x86_VENDOR_MASK 0xff00 @@ -689,76 +577,6 @@ extern status_t get_cpuid(cpuid_info *info, uint32 eaxRegister, #endif -typedef enum platform_types { - B_BEBOX_PLATFORM = 0, - B_MAC_PLATFORM, - B_AT_CLONE_PLATFORM, - B_ENIAC_PLATFORM, - B_APPLE_II_PLATFORM, - B_CRAY_PLATFORM, - B_LISA_PLATFORM, - B_TI_994A_PLATFORM, - B_TIMEX_SINCLAIR_PLATFORM, - B_ORAC_1_PLATFORM, - B_HAL_PLATFORM, - B_BESM_6_PLATFORM, - B_MK_61_PLATFORM, - B_NINTENDO_64_PLATFORM, - B_AMIGA_PLATFORM, - B_ATARI_PLATFORM, - B_64_BIT_PC_PLATFORM -} platform_type; - -typedef struct { - bigtime_t active_time; /* usec of doing useful work since boot */ -} cpu_info; - - -typedef int32 machine_id[2]; /* unique machine ID */ - -typedef struct { - machine_id id; /* unique machine ID */ - bigtime_t boot_time; /* time of boot (usecs since 1/1/1970) */ - - int32 cpu_count; /* number of cpus */ - enum cpu_types cpu_type; /* type of cpu */ - int32 cpu_revision; /* revision # of cpu */ - cpu_info cpu_infos[8]; /* info about individual cpus */ - int64 cpu_clock_speed; /* processor clock speed (Hz) */ - int64 bus_clock_speed; /* bus clock speed (Hz) */ - enum platform_types platform_type; /* type of machine we're on */ - - int32 max_pages; /* total # of accessible pages */ - int32 used_pages; /* # of accessible pages in use */ - int32 page_faults; /* # of page faults */ - int32 max_sems; - int32 used_sems; - int32 max_ports; - int32 used_ports; - int32 max_threads; - int32 used_threads; - int32 max_teams; - int32 used_teams; - - char kernel_name[B_FILE_NAME_LENGTH]; - char kernel_build_date[B_OS_NAME_LENGTH]; - char kernel_build_time[B_OS_NAME_LENGTH]; - int64 kernel_version; - - bigtime_t _busy_wait_time; /* reserved for whatever */ - - int32 cached_pages; - uint32 abi; /* the system API */ - int32 ignored_pages; /* # of ignored/inaccessible pages */ - int32 pad; -} system_info; - -/* system private, use macro instead */ -extern status_t _get_system_info(system_info *info, size_t size); - -#define get_system_info(info) \ - _get_system_info((info), sizeof(*(info))) - extern int32 is_computer_on(void); extern double is_computer_on_fire(void); diff --git a/headers/private/kernel/arch/system_info.h b/headers/private/kernel/arch/system_info.h index 3a5fb24c8e..f765be64bd 100644 --- a/headers/private/kernel/arch/system_info.h +++ b/headers/private/kernel/arch/system_info.h @@ -18,7 +18,7 @@ extern "C" { #endif status_t arch_system_info_init(struct kernel_args *args); -status_t arch_get_system_info(system_info *info, size_t size); +void arch_fill_topology_node(cpu_topology_node_info* node, int32 cpu); #ifdef __cplusplus } diff --git a/headers/private/kernel/ksystem_info.h b/headers/private/kernel/ksystem_info.h index 9ff900cd33..1fc466d8ee 100644 --- a/headers/private/kernel/ksystem_info.h +++ b/headers/private/kernel/ksystem_info.h @@ -21,7 +21,11 @@ status_t system_info_init(struct kernel_args *args); status_t system_notifications_init(); const char* get_haiku_revision(void); -status_t _user_get_system_info(system_info *userInfo, size_t size); +status_t _user_get_system_info(system_info *userInfo); +status_t _user_get_cpu_info(uint32 firstCPU, uint32 cpuCount, cpu_info* info); +status_t _user_get_cpu_topology_info(cpu_topology_node_info* topologyInfos, + uint32* topologyInfoCount); + status_t _user_get_system_info_etc(int32 id, void *buffer, size_t bufferSize); diff --git a/headers/private/shared/cpu_type.h b/headers/private/shared/cpu_type.h index d71983e14f..b84fa694bd 100644 --- a/headers/private/shared/cpu_type.h +++ b/headers/private/shared/cpu_type.h @@ -1,5 +1,6 @@ /* * Copyright 2004-2013, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2013, Paweł Dziepak, pdziepak@quarnos.org. * Distributed under the terms of the MIT License. */ @@ -18,8 +19,9 @@ extern "C" { #endif -const char *get_cpu_vendor_string(enum cpu_types type); -const char *get_cpu_model_string(const system_info *info); +static const char* get_cpu_vendor_string(enum cpu_vendor cpuVendor); +static const char* get_cpu_model_string(enum cpu_platform platform, + enum cpu_vendor cpuVendor, uint32 cpuModel); void get_cpu_type(char *vendorBuffer, size_t vendorSize, char *modelBuffer, size_t modelSize); int32 get_rounded_cpu_speed(void); @@ -165,36 +167,16 @@ parse_amd(const char* name) #endif -const char * -get_cpu_vendor_string(enum cpu_types type) +static const char* +get_cpu_vendor_string(enum cpu_vendor cpuVendor) { -#if __POWERPC__ - /* We're not that nice here. */ - return "IBM/Motorola"; -#endif -#if defined(__INTEL__) || defined(__x86_64__) - /* Determine x86 vendor name */ - switch (type & B_CPU_x86_VENDOR_MASK) { - case B_CPU_INTEL_x86: - return "Intel"; - case B_CPU_AMD_x86: - return "AMD"; - case B_CPU_CYRIX_x86: - return "Cyrix"; - case B_CPU_IDT_x86: - /* IDT was bought by VIA */ - if (((type >> 8) & 0xf) >= 6) - return "VIA"; - return "IDT"; - case B_CPU_RISE_x86: - return "Rise"; - case B_CPU_TRANSMETA_x86: - return "Transmeta"; + static const char* vendorStrings[] = { + NULL, "AMD", "Cyrix", "IDT", "Intel", "Rise", "Transmeta", "VIA", + }; - default: - return NULL; - } -#endif + if ((size_t)cpuVendor >= sizeof(vendorStrings) / sizeof(const char*)) + return NULL; + return vendorStrings[cpuVendor]; } @@ -256,248 +238,217 @@ get_cpuid_model_string(char *name) #endif /* __INTEL__ || __x86_64__ */ -const char * -get_cpu_model_string(const system_info *info) +static const char* +get_cpu_model_string(enum cpu_platform platform, enum cpu_vendor cpuVendor, + uint32 cpuModel) { #if defined(__INTEL__) || defined(__x86_64__) char cpuidName[49]; - /* for use with get_cpuid_model_string() */ -#endif /* __INTEL__ || __x86_64__ */ +#endif + + (void)cpuVendor; + (void)cpuModel; - /* Determine CPU type */ - switch (info->cpu_type) { -#if __POWERPC__ - case B_CPU_PPC_603: - return "603"; - case B_CPU_PPC_603e: - return "603e"; - case B_CPU_PPC_750: - return "750"; - case B_CPU_PPC_604: - return "604"; - case B_CPU_PPC_604e: - return "604e"; - default: - return NULL; -#endif /* __POWERPC__ */ #if defined(__INTEL__) || defined(__x86_64__) - case B_CPU_x86: - return "Unknown x86"; + if (platform != B_CPU_x86 && platform != B_CPU_x86_64) + return NULL; - /* Intel */ - case B_CPU_INTEL_PENTIUM: - case B_CPU_INTEL_PENTIUM75: - return "Pentium"; - case B_CPU_INTEL_PENTIUM_486_OVERDRIVE: - case B_CPU_INTEL_PENTIUM75_486_OVERDRIVE: - return "Pentium OD"; - case B_CPU_INTEL_PENTIUM_MMX: - case B_CPU_INTEL_PENTIUM_MMX_MODEL_8: - return "Pentium MMX"; - case B_CPU_INTEL_PENTIUM_PRO: - return "Pentium Pro"; - case B_CPU_INTEL_PENTIUM_II_MODEL_3: - case B_CPU_INTEL_PENTIUM_II_MODEL_5: - return "Pentium II"; - case B_CPU_INTEL_CELERON: - case B_CPU_INTEL_CELERON_MODEL_22: - return "Celeron"; - case B_CPU_INTEL_PENTIUM_III: - case B_CPU_INTEL_PENTIUM_III_MODEL_8: - case B_CPU_INTEL_PENTIUM_III_MODEL_11: - case B_CPU_INTEL_PENTIUM_III_XEON: - return "Pentium III"; - case B_CPU_INTEL_PENTIUM_M: - case B_CPU_INTEL_PENTIUM_M_MODEL_13: - get_cpuid_model_string(cpuidName); - if (strcasestr(cpuidName, "Celeron") != NULL) - return "Pentium M Celeron"; - return "Pentium M"; - case B_CPU_INTEL_ATOM: - return "Atom"; - case B_CPU_INTEL_PENTIUM_CORE: - get_cpuid_model_string(cpuidName); - if (strcasestr(cpuidName, "Celeron") != NULL) - return "Core Celeron"; - return "Core"; - case B_CPU_INTEL_PENTIUM_CORE_2: - get_cpuid_model_string(cpuidName); - if (strcasestr(cpuidName, "Celeron") != NULL) - return "Core 2 Celeron"; - if (strcasestr(cpuidName, "Xeon") != NULL) - return "Core 2 Xeon"; - return "Core 2"; - case B_CPU_INTEL_PENTIUM_CORE_2_45_NM: - get_cpuid_model_string(cpuidName); - if (strcasestr(cpuidName, "Celeron") != NULL) - return "Core 2 Celeron"; - if (strcasestr(cpuidName, "Xeon") != NULL) - return "Core 2 Xeon"; - if (strcasestr(cpuidName, "Pentium") != NULL) - return "Pentium"; - if (strcasestr(cpuidName, "Extreme") != NULL) - return "Core 2 Extreme"; - return "Core 2"; - case B_CPU_INTEL_PENTIUM_CORE_I5_M430: - return "Core i5"; - case B_CPU_INTEL_PENTIUM_CORE_I7: - case B_CPU_INTEL_PENTIUM_CORE_I7_Q720: - get_cpuid_model_string(cpuidName); - if (strcasestr(cpuidName, "Xeon") != NULL) - return "Core i7 Xeon"; - return "Core i7"; - case B_CPU_INTEL_PENTIUM_IV: - case B_CPU_INTEL_PENTIUM_IV_MODEL_1: - case B_CPU_INTEL_PENTIUM_IV_MODEL_2: - case B_CPU_INTEL_PENTIUM_IV_MODEL_3: - case B_CPU_INTEL_PENTIUM_IV_MODEL_4: - get_cpuid_model_string(cpuidName); - if (strcasestr(cpuidName, "Celeron") != NULL) - return "Pentium 4 Celeron"; - if (strcasestr(cpuidName, "Xeon") != NULL) - return "Pentium 4 Xeon"; - return "Pentium 4"; + uint16 family = ((cpuModel >> 8) & 0xf) | ((cpuModel >> 16) & 0xff0); + uint16 model = ((cpuModel >> 4) & 0xf) | ((cpuModel >> 12) & 0xf0); + uint8 stepping = cpuModel & 0xf; - /* AMD */ - case B_CPU_AMD_K5_MODEL_0: - case B_CPU_AMD_K5_MODEL_1: - case B_CPU_AMD_K5_MODEL_2: - case B_CPU_AMD_K5_MODEL_3: - return "K5"; - case B_CPU_AMD_K6_MODEL_6: - case B_CPU_AMD_K6_MODEL_7: - return "K6"; - case B_CPU_AMD_K6_2: - return "K6-2"; - case B_CPU_AMD_K6_III: - case B_CPU_AMD_K6_III_MODEL_13: - return "K6-III"; - case B_CPU_AMD_GEODE_LX: - return "Geode LX"; - case B_CPU_AMD_ATHLON_MODEL_1: - case B_CPU_AMD_ATHLON_MODEL_2: - case B_CPU_AMD_ATHLON_THUNDERBIRD: - return "Athlon"; - case B_CPU_AMD_ATHLON_XP_MODEL_6: - case B_CPU_AMD_ATHLON_XP_MODEL_7: - case B_CPU_AMD_ATHLON_XP_MODEL_8: - case B_CPU_AMD_ATHLON_XP_MODEL_10: - return "Athlon XP"; - case B_CPU_AMD_DURON: - return "Duron"; - case B_CPU_AMD_ATHLON_64_MODEL_3: - case B_CPU_AMD_ATHLON_64_MODEL_4: - case B_CPU_AMD_ATHLON_64_MODEL_7: - case B_CPU_AMD_ATHLON_64_MODEL_8: - case B_CPU_AMD_ATHLON_64_MODEL_11: - case B_CPU_AMD_ATHLON_64_MODEL_12: - case B_CPU_AMD_ATHLON_64_MODEL_14: - case B_CPU_AMD_ATHLON_64_MODEL_15: - case B_CPU_AMD_ATHLON_64_MODEL_20: - case B_CPU_AMD_ATHLON_64_MODEL_23: - case B_CPU_AMD_ATHLON_64_MODEL_24: - case B_CPU_AMD_ATHLON_64_MODEL_27: - case B_CPU_AMD_ATHLON_64_MODEL_28: - case B_CPU_AMD_ATHLON_64_MODEL_31: - case B_CPU_AMD_ATHLON_64_MODEL_35: - case B_CPU_AMD_ATHLON_64_MODEL_43: - case B_CPU_AMD_ATHLON_64_MODEL_44: - case B_CPU_AMD_ATHLON_64_MODEL_47: - case B_CPU_AMD_ATHLON_64_MODEL_63: - case B_CPU_AMD_ATHLON_64_MODEL_79: - case B_CPU_AMD_ATHLON_64_MODEL_95: - case B_CPU_AMD_ATHLON_64_MODEL_127: - return "Athlon 64"; - case B_CPU_AMD_OPTERON_MODEL_5: - case B_CPU_AMD_OPTERON_MODEL_21: - case B_CPU_AMD_OPTERON_MODEL_33: - case B_CPU_AMD_OPTERON_MODEL_37: - case B_CPU_AMD_OPTERON_MODEL_39: - return "Opteron"; - case B_CPU_AMD_TURION_64_MODEL_36: - case B_CPU_AMD_TURION_64_MODEL_76: - case B_CPU_AMD_TURION_64_MODEL_104: - return "Turion 64"; - case B_CPU_AMD_PHENOM_MODEL_2: - return "Phenom"; - case B_CPU_AMD_PHENOM_II_MODEL_4: - case B_CPU_AMD_PHENOM_II_MODEL_5: - case B_CPU_AMD_PHENOM_II_MODEL_6: - case B_CPU_AMD_PHENOM_II_MODEL_10: - get_cpuid_model_string(cpuidName); - if (strcasestr(cpuidName, "Athlon") != NULL) - return "Athlon II"; - return "Phenom II"; - case B_CPU_AMD_A_SERIES: + if (cpuVendor == B_CPU_VENDOR_AMD) { + if (family == 5) { + if (model <= 3) + return "K5"; + if (model <= 7) + return "K6"; + if (model == 8) + return "K6-2"; + if (model == 9 || model == 0xd) + return "K6-III"; + if (model == 0xa) + return "Geode LX"; + } else if (family == 6) { + if (model <= 2 || model == 4) + return "Athlon"; + if (model == 3) + return "Duron"; + if (model <= 8 || model == 0xa) + return "Athlon XP"; + } else if (family == 0xf) { + if (model <= 4 || model == 7 || model == 8 + || (model >= 0xb && model <= 0xf) || model == 0x14 + || model == 0x18 || model == 0x1b || model == 0x1c + || model == 0x1f || model == 0x23 || model == 0x2b + || model == 0x2c + || ((model & 0xf) == 0xf && model >= 0x2f && model <= 0x7f)) { + return "Athlon 64"; + } + if (model == 5 || model == 0x15 || model == 0x21 || model == 0x25 + || model == 0x27) { + return "Opteron"; + } + if (model == 0x24 || model == 0x4c || model == 0x68) + return "Turion 64"; + } else if (family == 0x1f) { + if (model == 2) + return "Phenom"; + if ((model >= 4 && model <= 6) || model == 0xa) { + get_cpuid_model_string(cpuidName); + if (strcasestr(cpuidName, "Athlon") != NULL) + return "Athlon II"; + return "Phenom II"; + } + } else if (family == 0x3f) return "A-Series"; - case B_CPU_AMD_C_SERIES: - return "C-Series"; - case B_CPU_AMD_E_SERIES: - return "E-Series"; - case B_CPU_AMD_FX_SERIES_MODEL_1: - case B_CPU_AMD_FX_SERIES_MODEL_2: + else if (family == 0x5f) { + if (model == 1) + return "C-Series"; + if (model == 2) + return "E-Series"; + } else if (family == 0x6f) return "FX-Series"; - /* Transmeta */ - case B_CPU_TRANSMETA_CRUSOE: - return "Crusoe"; - case B_CPU_TRANSMETA_EFFICEON: - case B_CPU_TRANSMETA_EFFICEON_2: - return "Efficeon"; - - /* IDT/VIA */ - case B_CPU_IDT_WINCHIP_C6: - return "WinChip C6"; - case B_CPU_IDT_WINCHIP_2: - return "WinChip 2"; - case B_CPU_VIA_C3_SAMUEL: - return "C3 Samuel"; - case B_CPU_VIA_C3_SAMUEL_2: - /* stepping identified the model */ - if ((info->cpu_revision & 0xf) < 8) - return "C3 Eden/Samuel 2"; - return "C3 Ezra"; - case B_CPU_VIA_C3_EZRA_T: - return "C3 Ezra-T"; - case B_CPU_VIA_C3_NEHEMIAH: - /* stepping identified the model */ - if ((info->cpu_revision & 0xf) < 8) - return "C3 Nehemiah"; - return "C3 Eden-N"; - case B_CPU_VIA_C7_ESTHER: - case B_CPU_VIA_C7_ESTHER_2: - return "C7"; - case B_CPU_VIA_NANO_ISAIAH: - return "Nano"; - - /* Cyrix/VIA */ - case B_CPU_CYRIX_GXm: - return "GXm"; - case B_CPU_CYRIX_6x86MX: - return "6x86MX"; - - /* Rise */ - case B_CPU_RISE_mP6: - return "mP6"; - - /* National Semiconductor */ - case B_CPU_NATIONAL_GEODE_GX1: - return "Geode GX1"; - - default: - if ((info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86) { - // Fallback to manual parsing of the model string - get_cpuid_model_string(cpuidName); - return parse_intel(cpuidName); - } - if ((info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_AMD_x86) { - // Fallback to manual parsing of the model string - get_cpuid_model_string(cpuidName); - return parse_amd(cpuidName); - } - return NULL; -#endif /* __INTEL__ || __x86_64__ */ + // Fallback to manual parsing of the model string + get_cpuid_model_string(cpuidName); + return parse_amd(cpuidName); } + + if (cpuVendor == B_CPU_VENDOR_CYRIX) { + if (family == 5 && model == 4) + return "GXm"; + if (family == 6) + return "6x86MX"; + return NULL; + } + + if (cpuVendor == B_CPU_VENDOR_INTEL) { + if (family == 5) { + if (model == 1 || model == 2) + return "Pentium"; + if (model == 3 || model == 9) + return "Pentium OD"; + if (model == 4 || model == 8) + return "Pentium MMX"; + } else if (family == 6) { + if (model == 1) + return "Pentium Pro"; + if (model == 3 || model == 5) + return "Pentium II"; + if (model == 6) + return "Celeron"; + if (model == 7 || model == 8 || model == 0xa || model == 0xb) + return "Pentium III"; + if (model == 9 || model == 0xd) { + get_cpuid_model_string(cpuidName); + if (strcasestr(cpuidName, "Celeron") != NULL) + return "Pentium M Celeron"; + return "Pentium M"; + } + if (model == 0x1c || model == 0x26 || model == 0x36) + return "Atom"; + if (model == 0xe) { + get_cpuid_model_string(cpuidName); + if (strcasestr(cpuidName, "Celeron") != NULL) + return "Core Celeron"; + return "Core"; + } + if (model == 0xf || model == 0x17) { + get_cpuid_model_string(cpuidName); + if (strcasestr(cpuidName, "Celeron") != NULL) + return "Core 2 Celeron"; + if (strcasestr(cpuidName, "Xeon") != NULL) + return "Core 2 Xeon"; + if (strcasestr(cpuidName, "Pentium") != NULL) + return "Pentium"; + if (strcasestr(cpuidName, "Extreme") != NULL) + return "Core 2 Extreme"; + return "Core 2"; + } + if (model == 0x25) + return "Core i5"; + if (model == 0x1a || model == 0x1e) { + get_cpuid_model_string(cpuidName); + if (strcasestr(cpuidName, "Xeon") != NULL) + return "Core i7 Xeon"; + return "Core i7"; + } + } else if (family == 0xf) { + if (model <= 4) { + get_cpuid_model_string(cpuidName); + if (strcasestr(cpuidName, "Celeron") != NULL) + return "Pentium 4 Celeron"; + if (strcasestr(cpuidName, "Xeon") != NULL) + return "Pentium 4 Xeon"; + return "Pentium 4"; + } + } + + // Fallback to manual parsing of the model string + get_cpuid_model_string(cpuidName); + return parse_intel(cpuidName); + } + + if (cpuVendor == B_CPU_VENDOR_NATIONAL_SEMICONDUCTOR) { + if (family == 5) { + if (model == 4) + return "Geode GX1"; + if (model == 5) + return "Geode GX2"; + return NULL; + } + } + + if (cpuVendor == B_CPU_VENDOR_RISE) { + if (family == 5) + return "mP6"; + return NULL; + } + + if (cpuVendor == B_CPU_VENDOR_TRANSMETA) { + if (family == 5 && model == 4) + return "Crusoe"; + if (family == 0xf && (model == 2 || model == 3)) + return "Efficeon"; + return NULL; + } + + if (cpuVendor == B_CPU_VENDOR_VIA) { + if (family == 5) { + if (model == 4) + return "WinChip C6"; + if (model == 8) + return "WinChip 2"; + if (model == 9) + return "WinChip 3"; + return NULL; + } else if (family == 6) { + if (model == 6) + return "C3 Samuel"; + if (model == 7) { + if (stepping < 8) + return "C3 Eden/Samuel 2"; + return "C3 Ezra"; + } + if (model == 8) + return "C3 Ezra-T"; + if (model == 9) { + if (stepping < 8) + return "C3 Nehemiah"; + return "C3 Ezra-N"; + } + if (model == 0xa || model == 0xd) + return "C7"; + if (model == 0xf) + return "Nano"; + return NULL; + } + } + +#endif + + return NULL; } @@ -506,15 +457,42 @@ get_cpu_type(char *vendorBuffer, size_t vendorSize, char *modelBuffer, size_t modelSize) { const char *vendor, *model; - system_info info; - get_system_info(&info); + uint32 topologyNodeCount = 0; + cpu_topology_node_info* topology = NULL; + get_cpu_topology_info(NULL, &topologyNodeCount); + if (topologyNodeCount != 0) + topology = new cpu_topology_node_info[topologyNodeCount]; + get_cpu_topology_info(topology, &topologyNodeCount); - vendor = get_cpu_vendor_string(info.cpu_type); + enum cpu_platform platform = B_CPU_UNKNOWN; + enum cpu_vendor cpuVendor = B_CPU_VENDOR_UNKNOWN; + uint32 cpuModel = 0; + for (uint32 i = 0; i < topologyNodeCount; i++) { + switch (topology[i].type) { + case B_TOPOLOGY_ROOT: + platform = topology[i].data.root.platform; + break; + + case B_TOPOLOGY_PACKAGE: + cpuVendor = topology[i].data.package.vendor; + break; + + case B_TOPOLOGY_CORE: + cpuModel = topology[i].data.core.model; + break; + + default: + break; + } + } + delete[] topology; + + vendor = get_cpu_vendor_string(cpuVendor); if (vendor == NULL) vendor = "Unknown"; - model = get_cpu_model_string(&info); + model = get_cpu_model_string(platform, cpuVendor, cpuModel); if (model == NULL) model = "Unknown"; @@ -533,14 +511,27 @@ get_cpu_type(char *vendorBuffer, size_t vendorSize, char *modelBuffer, int32 get_rounded_cpu_speed(void) { - system_info info; + uint32 topologyNodeCount = 0; + cpu_topology_node_info* topology = NULL; + get_cpu_topology_info(NULL, &topologyNodeCount); + if (topologyNodeCount != 0) + topology = new cpu_topology_node_info[topologyNodeCount]; + get_cpu_topology_info(topology, &topologyNodeCount); + + uint64 cpuFrequency = 0; + for (uint32 i = 0; i < topologyNodeCount; i++) { + if (topology[i].type == B_TOPOLOGY_CORE) { + cpuFrequency = topology[i].data.core.default_frequency; + break; + } + } + delete[] topology; int target, frac, delta; int freqs[] = { 100, 50, 25, 75, 33, 67, 20, 40, 60, 80, 10, 30, 70, 90 }; uint x; - get_system_info(&info); - target = info.cpu_clock_speed / 1000000; + target = cpuFrequency / 1000000; frac = target % 100; delta = -frac; diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index 6b1abb6b0b..fd787c4cda 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -514,7 +514,13 @@ extern int64 _kern_atomic_get64(vint64 *value); #endif // ATOMIC64_FUNCS_ARE_SYSCALLS /* System informations */ -extern status_t _kern_get_system_info(system_info *info, size_t size); +extern status_t _kern_get_system_info(system_info* info); +extern status_t _kern_get_cpu_info(uint32 firstCPU, uint32 cpuCount, + cpu_info* info); +extern status_t _kern_get_cpu_topology_info( + cpu_topology_node_info* topologyInfos, + uint32* topologyInfoCount); + extern status_t _kern_get_system_info_etc(int32 id, void *buffer, size_t bufferSize); extern status_t _kern_analyze_scheduling(bigtime_t from, bigtime_t until, diff --git a/headers/private/system/system_info.h b/headers/private/system/system_info.h index 888c4423c8..89a47f6bac 100644 --- a/headers/private/system/system_info.h +++ b/headers/private/system/system_info.h @@ -63,6 +63,10 @@ extern "C" { #endif +status_t __get_system_info(system_info* info); +status_t __get_cpu_info(uint32 firstCPU, uint32 cpuCount, cpu_info* info); +status_t __get_cpu_topology_info(cpu_topology_node_info* topologyInfos, + uint32* topologyInfoCount); status_t __get_system_info_etc(int32 id, void* buffer, size_t bufferSize); status_t __start_watching_system(int32 object, uint32 flags, port_id port, diff --git a/src/apps/aboutsystem/AboutSystem.cpp b/src/apps/aboutsystem/AboutSystem.cpp index 48e71973fd..1748fabc95 100644 --- a/src/apps/aboutsystem/AboutSystem.cpp +++ b/src/apps/aboutsystem/AboutSystem.cpp @@ -615,9 +615,40 @@ AboutView::AboutView() strlcpy(processorLabel, B_TRANSLATE("Processor:"), sizeof(processorLabel)); + uint32 topologyNodeCount = 0; + cpu_topology_node_info* topology = NULL; + get_cpu_topology_info(NULL, &topologyNodeCount); + if (topologyNodeCount != 0) + topology = new cpu_topology_node_info[topologyNodeCount]; + get_cpu_topology_info(topology, &topologyNodeCount); + + enum cpu_platform platform = B_CPU_UNKNOWN; + enum cpu_vendor cpuVendor = B_CPU_VENDOR_UNKNOWN; + uint32 cpuModel = 0; + for (uint32 i = 0; i < topologyNodeCount; i++) { + switch (topology[i].type) { + case B_TOPOLOGY_ROOT: + platform = topology[i].data.root.platform; + break; + + case B_TOPOLOGY_PACKAGE: + cpuVendor = topology[i].data.package.vendor; + break; + + case B_TOPOLOGY_CORE: + cpuModel = topology[i].data.core.model; + break; + + default: + break; + } + } + + delete[] topology; + BString cpuType; - cpuType << get_cpu_vendor_string(systemInfo.cpu_type) - << " " << get_cpu_model_string(&systemInfo); + cpuType << get_cpu_vendor_string(cpuVendor) + << " " << get_cpu_model_string(platform, cpuVendor, cpuModel); BStringView* cpuView = new BStringView("cputext", cpuType.String()); cpuView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, diff --git a/src/apps/activitymonitor/DataSource.cpp b/src/apps/activitymonitor/DataSource.cpp index b7b15f0d24..9c954e1051 100644 --- a/src/apps/activitymonitor/DataSource.cpp +++ b/src/apps/activitymonitor/DataSource.cpp @@ -873,7 +873,7 @@ CPUUsageDataSource::Print(BString& text, int64 value) const int64 CPUUsageDataSource::NextValue(SystemInfo& info) { - bigtime_t active = info.Info().cpu_infos[fCPU].active_time; + bigtime_t active = info.CPUActiveTime(fCPU); int64 percent = int64(1000.0 * (active - fPreviousActive) / (info.Time() - fPreviousTime)); @@ -1018,8 +1018,8 @@ CPUCombinedUsageDataSource::NextValue(SystemInfo& info) int32 running = 0; bigtime_t active = 0; - for (int32 cpu = 0; cpu < info.Info().cpu_count; cpu++) { - active += info.Info().cpu_infos[cpu].active_time; + for (uint32 cpu = 0; cpu < info.CPUCount(); cpu++) { + active += info.CPUActiveTime(cpu); running++; // TODO: take disabled CPUs into account } diff --git a/src/apps/activitymonitor/SystemInfo.cpp b/src/apps/activitymonitor/SystemInfo.cpp index 423c2bd72d..2416e4a2a0 100644 --- a/src/apps/activitymonitor/SystemInfo.cpp +++ b/src/apps/activitymonitor/SystemInfo.cpp @@ -24,6 +24,8 @@ SystemInfo::SystemInfo(SystemInfoHandler* handler) fMediaBuffers(0) { get_system_info(&fSystemInfo); + fCPUInfos = new cpu_info[fSystemInfo.cpu_count]; + get_cpu_info(0, fSystemInfo.cpu_count, fCPUInfos); __get_system_info_etc(B_MEMORY_INFO, &fMemoryInfo, sizeof(system_memory_info)); @@ -40,6 +42,7 @@ SystemInfo::SystemInfo(SystemInfoHandler* handler) SystemInfo::~SystemInfo() { + delete[] fCPUInfos; } diff --git a/src/apps/activitymonitor/SystemInfo.h b/src/apps/activitymonitor/SystemInfo.h index 2bee16c708..66e900b27b 100644 --- a/src/apps/activitymonitor/SystemInfo.h +++ b/src/apps/activitymonitor/SystemInfo.h @@ -42,6 +42,8 @@ public: bigtime_t Time() const { return fTime; } uint32 CPUCount() const { return fSystemInfo.cpu_count; } + bigtime_t CPUActiveTime(uint32 cpu) const + { return fCPUInfos[cpu].active_time; } const system_info& Info() const { return fSystemInfo; } uint64 NetworkReceived(); @@ -61,6 +63,7 @@ private: void _RetrieveNetwork(); system_info fSystemInfo; + cpu_info* fCPUInfos; system_memory_info fMemoryInfo; bigtime_t fTime; bool fRetrievedNetwork; diff --git a/src/apps/debugger/controllers/DebugReportGenerator.cpp b/src/apps/debugger/controllers/DebugReportGenerator.cpp index bf45375753..476b99e4ff 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.cpp +++ b/src/apps/debugger/controllers/DebugReportGenerator.cpp @@ -234,11 +234,40 @@ DebugReportGenerator::_GenerateReportHeader(BString& _output) SystemInfo sysInfo; + uint32 topologyNodeCount = 0; + cpu_topology_node_info* topology = NULL; + get_cpu_topology_info(NULL, &topologyNodeCount); + if (topologyNodeCount != 0) + topology = new cpu_topology_node_info[topologyNodeCount]; + get_cpu_topology_info(topology, &topologyNodeCount); + + cpu_platform platform = B_CPU_UNKNOWN; + cpu_vendor cpuVendor = B_CPU_VENDOR_UNKNOWN; + uint32 cpuModel = 0; + for (uint32 i = 0; i < topologyNodeCount; i++) { + switch (topology[i].type) { + case B_TOPOLOGY_ROOT: + platform = topology[i].data.root.platform; + break; + + case B_TOPOLOGY_PACKAGE: + cpuVendor = topology[i].data.package.vendor; + break; + + case B_TOPOLOGY_CORE: + cpuModel = topology[i].data.core.model; + break; + + default: + break; + } + } + if (fDebuggerInterface->GetSystemInfo(sysInfo) == B_OK) { const system_info &info = sysInfo.GetSystemInfo(); data.SetToFormat("CPU(s): %" B_PRId32 "x %s %s\n", - info.cpu_count, get_cpu_vendor_string(info.cpu_type), - get_cpu_model_string(&info)); + info.cpu_count, get_cpu_vendor_string(cpuVendor), + get_cpu_model_string(platform, cpuVendor, cpuModel)); _output << data; char maxSize[32]; char usedSize[32]; @@ -256,6 +285,7 @@ DebugReportGenerator::_GenerateReportHeader(BString& _output) _output << data; } + delete[] topology; return B_OK; } diff --git a/src/apps/diskprobe/TypeEditors.cpp b/src/apps/diskprobe/TypeEditors.cpp index 39bfbf8cb2..3cf2d46948 100644 --- a/src/apps/diskprobe/TypeEditors.cpp +++ b/src/apps/diskprobe/TypeEditors.cpp @@ -187,7 +187,7 @@ TypeEditorView::TypeMatches() system_info info; get_system_info(&info); - return fEditor.FileSize() / B_PAGE_SIZE < info.max_pages / 2; + return uint64(fEditor.FileSize()) / B_PAGE_SIZE < info.max_pages / 2; } diff --git a/src/apps/packageinstaller/PackageInfo.cpp b/src/apps/packageinstaller/PackageInfo.cpp index 93549344ad..c0f212e46e 100644 --- a/src/apps/packageinstaller/PackageInfo.cpp +++ b/src/apps/packageinstaller/PackageInfo.cpp @@ -45,6 +45,21 @@ enum { P_SCRIPT }; +typedef enum { + B_BEBOX_PLATFORM = 0, + B_MAC_PLATFORM, + B_AT_CLONE_PLATFORM, + B_ENIAC_PLATFORM, + B_APPLE_II_PLATFORM, + B_CRAY_PLATFORM, + B_LISA_PLATFORM, + B_TI_994A_PLATFORM, + B_TIMEX_SINCLAIR_PLATFORM, + B_ORAC_1_PLATFORM, + B_HAL_PLATFORM, + B_INVALID_PLATFORM +} platform_type; + PackageInfo::PackageInfo() : @@ -131,8 +146,19 @@ PackageInfo::Parse() const char padding[7] = { 0, 0, 0, 0, 0, 0, 0 }; - system_info sysinfo; - get_system_info(&sysinfo); + platform_type thisPlatform = B_INVALID_PLATFORM; + cpu_topology_node_info topologyRoot; + uint32 topologyNodeCount = 1; + if (get_cpu_topology_info(&topologyRoot, &topologyNodeCount) == B_OK) { + switch (topologyRoot.data.root.platform) { + case B_CPU_x86: + thisPlatform = B_AT_CLONE_PLATFORM; + break; + + default: + break; + } + } uint64 infoOffset = 0, groupsOffset = 0; uint64 length = 0; @@ -843,8 +869,7 @@ PackageInfo::Parse() parser_debug("Padding!\n"); if (platform != 0xffffffff - && static_cast(platform) - != sysinfo.platform_type) { + && static_cast(platform) != thisPlatform) { // If the file/directory/item's platform is different than the // target platform (or different than the 'any' constant), // ignore this file diff --git a/src/apps/processcontroller/MemoryBarMenu.cpp b/src/apps/processcontroller/MemoryBarMenu.cpp index cdd8a925b4..125189dee0 100644 --- a/src/apps/processcontroller/MemoryBarMenu.cpp +++ b/src/apps/processcontroller/MemoryBarMenu.cpp @@ -45,7 +45,7 @@ MemoryBarMenu::MemoryBarMenu(const char* name, info_pack* infos, system_info& sy fTeamList = (team_id*)malloc(sizeof (team_id) * fTeamCount); - int k; + unsigned int k; for (k = 0; k < systemInfo.used_teams; k++) { fTeamList[k] = infos[k].team_info.team; } @@ -124,7 +124,7 @@ MemoryBarMenu::Pulse() info_pack infos; item = NULL; while (get_next_team_info(&cookie, &infos.team_info) == B_OK) { - int j = 0; + unsigned int j = 0; while (j < fTeamCount && infos.team_info.team != fTeamList[j]) { j++; } diff --git a/src/apps/processcontroller/MemoryBarMenu.h b/src/apps/processcontroller/MemoryBarMenu.h index 7f54961c41..627619608f 100644 --- a/src/apps/processcontroller/MemoryBarMenu.h +++ b/src/apps/processcontroller/MemoryBarMenu.h @@ -44,7 +44,7 @@ class MemoryBarMenu : public BMenu { private: team_id* fTeamList; - int fTeamCount; + unsigned int fTeamCount; MRecycleItem* fRecycleList; int fRecycleCount; bigtime_t fLastTotalTime; diff --git a/src/apps/processcontroller/ProcessController.cpp b/src/apps/processcontroller/ProcessController.cpp index 8e9765ea35..0e4a0d08b5 100644 --- a/src/apps/processcontroller/ProcessController.cpp +++ b/src/apps/processcontroller/ProcessController.cpp @@ -77,7 +77,7 @@ const rgb_color kKernelBlue = {20, 20, 231, 255}; const rgb_color kIdleGreen = {110, 190,110, 255}; ProcessController* gPCView; -int32 gCPUcount; +uint32 gCPUcount; rgb_color gUserColor; rgb_color gUserColorSelected; rgb_color gIdleColor; @@ -435,10 +435,10 @@ ProcessController::MessageReceived(BMessage *message) case 'CPU ': { - int32 cpu; - if (message->FindInt32 ("cpu", &cpu) == B_OK) { + uint32 cpu; + if (message->FindInt32("cpu", (int32*)&cpu) == B_OK) { bool last = true; - for (int p = 0; p < gCPUcount; p++) { + for (unsigned int p = 0; p < gCPUcount; p++) { if (p != cpu && _kern_cpu_enabled(p)) { last = false; break; @@ -609,7 +609,7 @@ ProcessController::DoDraw(bool force) SetHighColor(frame_color); StrokeRect(BRect(left - 1, top - 1, right, bottom + 1)); if (gCPUcount > 1 && layout[gCPUcount].cpu_inter == 1) { - for (int x = 1; x < gCPUcount; x++) + for (unsigned int x = 1; x < gCPUcount; x++) StrokeLine(BPoint(left + x * barWidth + x - 1, top), BPoint(left + x * barWidth + x - 1, bottom)); } @@ -619,7 +619,7 @@ ProcessController::DoDraw(bool force) StrokeRect(BRect(leftMem - 1, top - 1, leftMem + layout[gCPUcount].mem_width, bottom + 1)); - for (int x = 0; x < gCPUcount; x++) { + for (unsigned int x = 0; x < gCPUcount; x++) { right = left + barWidth - 1; float rem = fCPUTimes[x] * (h + 1); float barHeight = floorf (rem); @@ -697,14 +697,17 @@ ProcessController::Update() get_system_info(&info); bigtime_t now = system_time(); + cpu_info* cpuInfos = new cpu_info[gCPUcount]; + get_cpu_info(0, gCPUcount, cpuInfos); + fMemoryUsage = float(info.used_pages) / float(info.max_pages); // Calculate work done since last call to Update() for each CPU - for (int x = 0; x < gCPUcount; x++) { - bigtime_t load = info.cpu_infos[x].active_time - fPrevActive[x]; + for (unsigned int x = 0; x < gCPUcount; x++) { + bigtime_t load = cpuInfos[x].active_time - fPrevActive[x]; bigtime_t passed = now - fPrevTime; float cpuTime = float(load) / float(passed); - fPrevActive[x] = info.cpu_infos[x].active_time; + fPrevActive[x] = cpuInfos[x].active_time; if (load > passed) fPrevActive[x] -= load - passed; // save overload for next period... if (cpuTime < 0) @@ -714,6 +717,8 @@ ProcessController::Update() fCPUTimes[x] = cpuTime; } fPrevTime = now; + + delete[] cpuInfos; } @@ -725,7 +730,8 @@ thread_popup(void *arg) { Tpopup_param* param = (Tpopup_param*) arg; int32 mcookie, hcookie; - long m, h; + unsigned long m; + long h; BMenuItem* item; bool top = param->top; @@ -797,7 +803,7 @@ thread_popup(void *arg) // CPU on/off section if (gCPUcount > 1) { - for (int i = 0; i < gCPUcount; i++) { + for (unsigned int i = 0; i < gCPUcount; i++) { char item_name[32]; sprintf (item_name, B_TRANSLATE("Processor %d"), i + 1); BMessage* m = new BMessage ('CPU '); diff --git a/src/apps/processcontroller/ProcessController.h b/src/apps/processcontroller/ProcessController.h index 80c3a08c2b..8317d17747 100644 --- a/src/apps/processcontroller/ProcessController.h +++ b/src/apps/processcontroller/ProcessController.h @@ -73,7 +73,7 @@ class ProcessController : public BView { }; extern ProcessController* gPCView; -extern int32 gCPUcount; +extern uint32 gCPUcount; extern rgb_color gIdleColor; extern rgb_color gIdleColorSelected; extern rgb_color gKernelColor; diff --git a/src/apps/processcontroller/TeamBarMenuItem.cpp b/src/apps/processcontroller/TeamBarMenuItem.cpp index 3c9e5e477a..5806a6ebac 100644 --- a/src/apps/processcontroller/TeamBarMenuItem.cpp +++ b/src/apps/processcontroller/TeamBarMenuItem.cpp @@ -51,7 +51,7 @@ TeamBarMenuItem::Init() if (fTeamID == B_SYSTEM_TEAM) { thread_info thinfos; bigtime_t idle = 0; - for (int t = 1; t <= gCPUcount; t++) + for (unsigned int t = 1; t <= gCPUcount; t++) if (get_thread_info(t, &thinfos) == B_OK) idle += thinfos.kernel_time + thinfos.user_time; fTeamUsageInfo.kernel_time += fTeamUsageInfo.user_time; @@ -213,9 +213,10 @@ TeamBarMenuItem::BarUpdate() bigtime_t idle = 0; if (fTeamID == B_SYSTEM_TEAM) { thread_info thinfos; - for (int t = 1; t <= gCPUcount; t++) + for (unsigned int t = 1; t <= gCPUcount; t++) { if (get_thread_info(t, &thinfos) == B_OK) idle += thinfos.kernel_time + thinfos.user_time; + } usage.kernel_time += usage.user_time; usage.user_time = idle; idle -= fTeamUsageInfo.user_time; diff --git a/src/apps/pulse/DeskbarPulseView.cpp b/src/apps/pulse/DeskbarPulseView.cpp index 959c49daca..b20c3236f0 100644 --- a/src/apps/pulse/DeskbarPulseView.cpp +++ b/src/apps/pulse/DeskbarPulseView.cpp @@ -75,9 +75,8 @@ void DeskbarPulseView::AttachedToWindow() { system_info sys_info; get_system_info(&sys_info); if (sys_info.cpu_count >= 2) { - for (int x = 0; x < sys_info.cpu_count; x++) { + for (unsigned int x = 0; x < sys_info.cpu_count; x++) cpu_menu_items[x]->SetTarget(messenger); - } } // Use a BMessageRunner to deliver periodic messsages instead diff --git a/src/apps/pulse/MiniPulseView.cpp b/src/apps/pulse/MiniPulseView.cpp index 923810f439..32804892e2 100644 --- a/src/apps/pulse/MiniPulseView.cpp +++ b/src/apps/pulse/MiniPulseView.cpp @@ -76,7 +76,7 @@ void MiniPulseView::Draw(BRect rect) { float bar_width = (bounds.Width()) / sys_info.cpu_count - 2; float right = bar_width + left; - for (int x = 0; x < sys_info.cpu_count; x++) { + for (unsigned int x = 0; x < sys_info.cpu_count; x++) { int bar_height = (int)(cpu_times[x] * (h + 1)); if (bar_height > h) bar_height = h; double rem = cpu_times[x] * (h + 1) - bar_height; @@ -131,9 +131,8 @@ void MiniPulseView::AttachedToWindow() { system_info sys_info; get_system_info(&sys_info); if (sys_info.cpu_count >= 2) { - for (int x = 0; x < sys_info.cpu_count; x++) { + for (unsigned int x = 0; x < sys_info.cpu_count; x++) cpu_menu_items[x]->SetTarget(messenger); - } } } diff --git a/src/apps/pulse/NormalPulseView.cpp b/src/apps/pulse/NormalPulseView.cpp index 632b6bfa5c..c23dd24b69 100644 --- a/src/apps/pulse/NormalPulseView.cpp +++ b/src/apps/pulse/NormalPulseView.cpp @@ -129,16 +129,34 @@ NormalPulseView::DetermineVendorAndProcessor() logo = PowerPCLogo; #endif #if __INTEL__ - - switch (sys_info.cpu_type & B_CPU_x86_VENDOR_MASK) { - case B_CPU_INTEL_x86: - logo = IntelLogo; - break; - - case B_CPU_AMD_x86: - logo = AmdLogo; - break; - }; + uint32 topologyNodeCount = 0; + cpu_topology_node_info* topology = NULL; + + get_cpu_topology_info(NULL, &topologyNodeCount); + if (topologyNodeCount != 0) + topology = new cpu_topology_node_info[topologyNodeCount]; + get_cpu_topology_info(topology, &topologyNodeCount); + + for (uint32 i = 0; i < topologyNodeCount; i++) { + if (topology[i].type == B_TOPOLOGY_PACKAGE) { + switch (topology[i].data.package.vendor) { + case B_CPU_VENDOR_INTEL: + logo = IntelLogo; + break; + + case B_CPU_VENDOR_AMD: + logo = AmdLogo; + break; + + default: + break; + } + + break; + } + } + + delete[] topology; #endif fCpuLogo->SetBits(logo, fCpuLogo->BitsLength(), 0, B_CMAP8); @@ -255,9 +273,8 @@ NormalPulseView::AttachedToWindow() system_info sys_info; get_system_info(&sys_info); if (sys_info.cpu_count >= 2) { - for (int x = 0; x < sys_info.cpu_count; x++) { + for (unsigned int x = 0; x < sys_info.cpu_count; x++) cpu_menu_items[x]->SetTarget(messenger); - } } } @@ -270,7 +287,7 @@ NormalPulseView::UpdateColors(BMessage *message) system_info sys_info; get_system_info(&sys_info); - for (int x = 0; x < sys_info.cpu_count; x++) { + for (unsigned int x = 0; x < sys_info.cpu_count; x++) { fProgressBars[x]->UpdateColors(color, fade); fCpuButtons[x]->UpdateColors(color); } diff --git a/src/apps/pulse/PulseApp.cpp b/src/apps/pulse/PulseApp.cpp index 659762c2ba..af2f6f471b 100644 --- a/src/apps/pulse/PulseApp.cpp +++ b/src/apps/pulse/PulseApp.cpp @@ -207,14 +207,14 @@ PulseApp::ShowAbout(bool asApplication) */ bool -LastEnabledCPU(int my_cpu) +LastEnabledCPU(unsigned int my_cpu) { system_info sys_info; get_system_info(&sys_info); if (sys_info.cpu_count == 1) return true; - for (int x = 0; x < sys_info.cpu_count; x++) { + for (unsigned int x = 0; x < sys_info.cpu_count; x++) { if (x == my_cpu) continue; if (_kern_cpu_enabled(x) == 1) diff --git a/src/apps/pulse/PulseApp.h b/src/apps/pulse/PulseApp.h index d51cd3f344..266af30d4f 100644 --- a/src/apps/pulse/PulseApp.h +++ b/src/apps/pulse/PulseApp.h @@ -32,7 +32,7 @@ private: void BuildPulse(); }; -extern bool LastEnabledCPU(int cpu); +extern bool LastEnabledCPU(unsigned int cpu); extern int GetMinimumViewWidth(); extern bool LoadInDeskbar(); extern void Usage(); diff --git a/src/apps/pulse/PulseView.cpp b/src/apps/pulse/PulseView.cpp index 9370875a59..5a31421aac 100644 --- a/src/apps/pulse/PulseView.cpp +++ b/src/apps/pulse/PulseView.cpp @@ -82,7 +82,7 @@ void PulseView::Init() { if (sys_info.cpu_count >= 2) { cpu_menu_items = new BMenuItem *[sys_info.cpu_count]; char temp[20]; - for (int x = 0; x < sys_info.cpu_count; x++) { + for (unsigned int x = 0; x < sys_info.cpu_count; x++) { sprintf(temp, "CPU %d", x + 1); BMessage *message = new BMessage(PV_CPU_MENU_ITEM); message->AddInt32("which", x); @@ -115,10 +115,14 @@ void PulseView::Update() { get_system_info(&sys_info); bigtime_t now = system_time(); + cpu_info* cpuInfos = new cpu_info[sys_info.cpu_count]; + get_cpu_info(0, sys_info.cpu_count, cpuInfos); + // Calculate work done since last call to Update() for each CPU - for (int x = 0; x < sys_info.cpu_count; x++) { - double cpu_time = (double)(sys_info.cpu_infos[x].active_time - prev_active[x]) / (now - prev_time); - prev_active[x] = sys_info.cpu_infos[x].active_time; + for (unsigned int x = 0; x < sys_info.cpu_count; x++) { + double cpu_time = (double)(cpuInfos[x].active_time - prev_active[x]) + / (now - prev_time); + prev_active[x] = cpuInfos[x].active_time; if (cpu_time < 0) cpu_time = 0; if (cpu_time > 1) cpu_time = 1; cpu_times[x] = cpu_time; @@ -131,6 +135,8 @@ void PulseView::Update() { } } prev_time = now; + + delete[] cpuInfos; } void PulseView::ChangeCPUState(BMessage *message) { diff --git a/src/bin/Jamfile b/src/bin/Jamfile index 06abda94e3..756782d067 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -48,7 +48,6 @@ StdBinCommands release.c renice.c rescan.c - sysinfo.cpp unchop.c uptime.cpp vmstat.cpp @@ -159,6 +158,7 @@ StdBinCommands # commands that need libstdc++ only StdBinCommands diff_zip.cpp + sysinfo.cpp : $(TARGET_LIBSTDC++) : $(haiku-utils_rsrc) ; # standard commands that need libbe.so, libtranslation.so, libsupc++.so diff --git a/src/bin/coreutils/src/uname.c b/src/bin/coreutils/src/uname.c index 16b0b33c94..1bf091458c 100644 --- a/src/bin/coreutils/src/uname.c +++ b/src/bin/coreutils/src/uname.c @@ -346,16 +346,20 @@ main (int argc, char **argv) #ifdef __HAIKU__ { - system_info sysinfo; - get_system_info(&sysinfo); - - switch (sysinfo.platform_type) { - case B_AT_CLONE_PLATFORM: - element = "x86"; - break; - case B_64_BIT_PC_PLATFORM: - element = "x86_64"; - break; + cpu_topology_node_info root; + uint32_t count = 1; + status_t error = get_cpu_topology_info(&root, &count); + if (error != B_OK || count < 1) + element = "unknown"; + else { + switch (root.data.root.platform) { + case B_CPU_x86: + element = "x86"; + break; + case B_CPU_x86_64: + element = "x86_64"; + break; + } } } #endif diff --git a/src/bin/sysinfo.cpp b/src/bin/sysinfo.cpp index 552b3b4f72..02dee0ec84 100644 --- a/src/bin/sysinfo.cpp +++ b/src/bin/sysinfo.cpp @@ -141,7 +141,8 @@ struct cache_description { static void -print_intel_cache_descriptors(enum cpu_types type, cpuid_info *info) +print_intel_cache_descriptors(enum cpu_vendor vendor, uint32 model, + cpuid_info *info) { uint8 cacheDescriptors[15]; // Max @@ -195,9 +196,8 @@ print_intel_cache_descriptors(enum cpu_types type, cpuid_info *info) if (cacheDescriptors[i] == sIntelCacheDescriptions[j].code) { if (cacheDescriptors[i] == 0x40) { printf("\tNo integrated L%u cache\n", - type >= B_CPU_INTEL_PENTIUM_IV - && (type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86 - ? 3 : 2); + ((model >> 8) & 0xf) == 0xf + && vendor == B_CPU_VENDOR_INTEL ? 3 : 2); } else printf("\t%s\n", sIntelCacheDescriptions[j].description); break; @@ -210,6 +210,7 @@ print_intel_cache_descriptors(enum cpu_types type, cpuid_info *info) } } + #endif // __INTEL__ || __x86_64__ @@ -466,12 +467,11 @@ print_features(uint32 features) #if defined(__INTEL__) || defined(__x86_64__) static void -print_processor_signature(system_info *sys_info, cpuid_info *info, +print_processor_signature(enum cpu_vendor vendor, cpuid_info *info, const char *prefix) { - if ((sys_info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_AMD_x86) { - + if (vendor == B_CPU_VENDOR_AMD) { printf("\t%s%sype %" B_PRIu32 ", family %" B_PRIu32 ", model %" B_PRIu32 ", stepping %" B_PRIu32 ", features 0x%08" B_PRIx32 "\n", prefix ? prefix : "", prefix && prefix[0] ? "t" : "T", @@ -482,8 +482,7 @@ print_processor_signature(system_info *sys_info, cpuid_info *info, ? info->eax_1.extended_model << 4 : 0), info->eax_1.stepping, info->eax_1.features); - } else if ((sys_info->cpu_type & B_CPU_x86_VENDOR_MASK) - == B_CPU_INTEL_x86) { + } else if (vendor == B_CPU_VENDOR_INTEL) { // model calculation is different for INTEL printf("\t%s%sype %" B_PRIu32 ", family %" B_PRIu32 ", model %" B_PRIu32 ", stepping %" B_PRIu32 ", features 0x%08" B_PRIx32 "\n", @@ -505,17 +504,33 @@ print_processor_signature(system_info *sys_info, cpuid_info *info, static void dump_platform(system_info *info) { - printf("%s\n", - info->platform_type == B_AT_CLONE_PLATFORM ? "IntelArchitecture" : - info->platform_type == B_MAC_PLATFORM ? "Macintosh" : - info->platform_type == B_BEBOX_PLATFORM ? "BeBox" : "unknown"); + cpu_topology_node_info root; + uint32 count = 1; + get_cpu_topology_info(&root, &count); + + const char* platform; + switch (root.data.root.platform) { + case B_CPU_x86: + platform = "IntelArchitecture"; + break; + + case B_CPU_x86_64: + platform = "IntelArchitecture (64 bit)"; + break; + + default: + platform = "unknown"; + break; + } + + printf("%s\n", platform); } #if defined(__INTEL__) || defined(__x86_64__) static void -dump_cpu(system_info *info, int32 cpu) +dump_cpu(enum cpu_vendor vendor, uint32 model, int32 cpu) { // References: // http://grafi.ii.pw.edu.pl/gbm/x86/cpuid.html @@ -573,7 +588,7 @@ dump_cpu(system_info *info, int32 cpu) else { // Intel CPUs don't seem to have the genuine vendor field printf("CPU #%" B_PRId32 ": %.12s\n", cpu, - (info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86 ? + vendor == B_CPU_VENDOR_INTEL ? baseInfo.eax_0.vendor_id : cpuInfo.eax_0.vendor_id); } } else { @@ -583,7 +598,7 @@ dump_cpu(system_info *info, int32 cpu) } get_cpuid(&cpuInfo, 1, cpu); - print_processor_signature(info, &cpuInfo, NULL); + print_processor_signature(vendor, &cpuInfo, NULL); print_features(cpuInfo.eax_1.features); if (maxStandardFunction >= 1) { @@ -595,17 +610,15 @@ dump_cpu(system_info *info, int32 cpu) /* Extended CPUID */ if (maxExtendedFunction >= 1) { get_cpuid(&cpuInfo, 0x80000001, cpu); - print_processor_signature(info, &cpuInfo, "Extended AMD: "); + print_processor_signature(vendor, &cpuInfo, "Extended AMD: "); - if ((info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_AMD_x86 - || (info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86) { + if (vendor == B_CPU_VENDOR_AMD || vendor == B_CPU_VENDOR_INTEL) { print_amd_features(cpuInfo.regs.edx); if (maxExtendedFunction >= 7) { get_cpuid(&cpuInfo, 0x80000007, cpu); print_amd_power_management_features(cpuInfo.regs.edx); } - } else if ((info->cpu_type & B_CPU_x86_VENDOR_MASK) - == B_CPU_TRANSMETA_x86) + } else if (vendor == B_CPU_VENDOR_TRANSMETA) print_transmeta_features(cpuInfo.regs.edx); } @@ -613,9 +626,8 @@ dump_cpu(system_info *info, int32 cpu) if (maxExtendedFunction >= 5) { if (!strncmp(baseInfo.eax_0.vendor_id, "CyrixInstead", 12)) { get_cpuid(&cpuInfo, 0x00000002, cpu); - print_intel_cache_descriptors(info->cpu_type, &cpuInfo); - } else if ((info->cpu_type & B_CPU_x86_VENDOR_MASK) - == B_CPU_INTEL_x86) { + print_intel_cache_descriptors(vendor, model, &cpuInfo); + } else if (vendor == B_CPU_VENDOR_INTEL) { // Intel does not support extended function 5 (but it does 6 hmm) print_intel_cache_desc(cpu); } else { @@ -628,7 +640,7 @@ dump_cpu(system_info *info, int32 cpu) get_cpuid(&cpuInfo, 2, cpu); if (cpuInfo.eax_2.call_num > 0) - print_intel_cache_descriptors(info->cpu_type, &cpuInfo); + print_intel_cache_descriptors(vendor, model, &cpuInfo); } while (cpuInfo.eax_2.call_num > 1); } @@ -657,28 +669,59 @@ dump_cpu(system_info *info, int32 cpu) static void dump_cpus(system_info *info) { - const char *vendor = get_cpu_vendor_string(info->cpu_type); - const char *model = get_cpu_model_string(info); + uint32 topologyNodeCount = 0; + cpu_topology_node_info* topology = NULL; + get_cpu_topology_info(NULL, &topologyNodeCount); + if (topologyNodeCount != 0) + topology = new cpu_topology_node_info[topologyNodeCount]; + get_cpu_topology_info(topology, &topologyNodeCount); + + enum cpu_platform platform = B_CPU_UNKNOWN; + enum cpu_vendor cpuVendor = B_CPU_VENDOR_UNKNOWN; + uint32 cpuModel = 0; + uint64 frequency = 0; + for (uint32 i = 0; i < topologyNodeCount; i++) { + switch (topology[i].type) { + case B_TOPOLOGY_ROOT: + platform = topology[i].data.root.platform; + break; + + case B_TOPOLOGY_PACKAGE: + cpuVendor = topology[i].data.package.vendor; + break; + + case B_TOPOLOGY_CORE: + cpuModel = topology[i].data.core.model; + frequency = topology[i].data.core.default_frequency; + break; + + default: + break; + } + } + delete[] topology; + + const char *vendor = get_cpu_vendor_string(cpuVendor); + const char *model = get_cpu_model_string(platform, cpuVendor, cpuModel); char modelString[32]; if (model == NULL && vendor == NULL) model = "(Unknown)"; else if (model == NULL) { model = modelString; - snprintf(modelString, 32, "(Unknown %x)", info->cpu_type); + snprintf(modelString, 32, "(Unknown %" B_PRIx32 ")", cpuModel); } printf("%" B_PRId32 " %s%s%s, revision %04" B_PRIx32 " running at %" - B_PRId64 "MHz (ID: 0x%08" B_PRIx32 " 0x%08" B_PRIx32 ")\n\n", + B_PRIu64 "MHz\n\n", info->cpu_count, vendor ? vendor : "", vendor ? " " : "", model, - info->cpu_revision, - info->cpu_clock_speed / 1000000, - info->id[0], info->id[1]); + cpuModel, + frequency / 1000000); #if defined(__INTEL__) || defined(__x86_64__) - for (int32 cpu = 0; cpu < info->cpu_count; cpu++) - dump_cpu(info, cpu); + for (uint32 cpu = 0; cpu < info->cpu_count; cpu++) + dump_cpu(cpuVendor, cpuModel, cpu); #endif // __INTEL__ || __x86_64__ } @@ -780,8 +823,7 @@ main(int argc, char *argv[]) const char *opt = argv[i]; if (strncmp(opt, "-id", strlen(opt)) == 0) { /* note: the original also assumes this option on "sysinfo -" */ - printf("0x%.8" B_PRIx32 " 0x%.8" B_PRIx32 "\n", info.id[0], - info.id[1]); + printf("%#.8x %#.8x\n", 0,0); } else if (strncmp(opt, "-cpu", strlen(opt)) == 0) { dump_cpus(&info); } else if (strncmp(opt, "-mem", strlen(opt)) == 0) { diff --git a/src/kits/tracker/TaskLoop.cpp b/src/kits/tracker/TaskLoop.cpp index 6a3b00ed95..c87fdc310f 100644 --- a/src/kits/tracker/TaskLoop.cpp +++ b/src/kits/tracker/TaskLoop.cpp @@ -172,8 +172,14 @@ ActivityLevel() bigtime_t time = 0; system_info sinfo; get_system_info(&sinfo); - for (int32 index = 0; index < sinfo.cpu_count; index++) - time += sinfo.cpu_infos[index].active_time; + + cpu_info* cpuInfos = new cpu_info[sinfo.cpu_count]; + get_cpu_info(0, sinfo.cpu_count, cpuInfos); + + for (uint32 index = 0; index < sinfo.cpu_count; index++) + time += cpuInfos[index].active_time; + + delete[] cpuInfos; return time / ((bigtime_t) sinfo.cpu_count); } diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 2dc6bb884c..3654a8b942 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -125,7 +125,7 @@ detect_simd() // supported across all CPUs found. uint32 systemSIMD = 0xffffffff; - for (int32 cpu = 0; cpu < systemInfo.cpu_count; cpu++) { + for (uint32 cpu = 0; cpu < systemInfo.cpu_count; cpu++) { cpuid_info cpuInfo; get_cpuid(&cpuInfo, 0, cpu); diff --git a/src/system/kernel/arch/x86/arch_system_info.cpp b/src/system/kernel/arch/x86/arch_system_info.cpp index 280ca0eb65..0544c8105b 100644 --- a/src/system/kernel/arch/x86/arch_system_info.cpp +++ b/src/system/kernel/arch/x86/arch_system_info.cpp @@ -17,9 +17,9 @@ #include -uint32 sCpuType; -int32 sCpuRevision; -int64 sCpuClockSpeed; +enum cpu_vendor sCPUVendor; +uint32 sCPUModel; +int64 sCPUClockSpeed; static bool @@ -60,87 +60,74 @@ get_cpuid(cpuid_info *info, uint32 eaxRegister, uint32 forCPU) status_t -arch_get_system_info(system_info *info, size_t size) +arch_system_info_init(struct kernel_args *args) { - info->cpu_type = (cpu_types)sCpuType; - info->cpu_revision = sCpuRevision; + // So far we don't have to care about heterogeneous x86 platforms. + cpu_ent* cpu = get_cpu_struct(); - // - various cpu_info - info->cpu_clock_speed = sCpuClockSpeed; - // - bus_clock_speed -#ifdef __x86_64__ - info->platform_type = B_64_BIT_PC_PLATFORM; -#else - info->platform_type = B_AT_CLONE_PLATFORM; -#endif + switch (cpu->arch.vendor) { + case VENDOR_AMD: + sCPUVendor = B_CPU_VENDOR_AMD; + break; + case VENDOR_CENTAUR: + sCPUVendor = B_CPU_VENDOR_VIA; + break; + case VENDOR_CYRIX: + sCPUVendor = B_CPU_VENDOR_CYRIX; + break; + case VENDOR_INTEL: + sCPUVendor = B_CPU_VENDOR_INTEL; + break; + case VENDOR_NSC: + sCPUVendor = B_CPU_VENDOR_NATIONAL_SEMICONDUCTOR; + break; + case VENDOR_RISE: + sCPUVendor = B_CPU_VENDOR_RISE; + break; + case VENDOR_TRANSMETA: + sCPUVendor = B_CPU_VENDOR_TRANSMETA; + break; + default: + sCPUVendor = B_CPU_VENDOR_UNKNOWN; + break; + } - // ToDo: clock speeds could be retrieved via SMBIOS/DMI + sCPUModel = (cpu->arch.extended_family << 20) + | (cpu->arch.extended_model << 16) | (cpu->arch.type << 12) + | (cpu->arch.family << 8) | (cpu->arch.model << 4) | cpu->arch.stepping; + + sCPUClockSpeed = args->arch_args.cpu_clock_speed; return B_OK; } -status_t -arch_system_info_init(struct kernel_args *args) +void +arch_fill_topology_node(cpu_topology_node_info* node, int32 cpu) { - // This is what you get if the CPU vendor is not recognized - // or the CPU does not support cpuid with eax == 1. - uint32 base; - uint32 model = 0; - cpu_ent *cpu = get_cpu_struct(); + switch (node->type) { + case B_TOPOLOGY_ROOT: +#if __INTEL__ + node->data.root.platform = B_CPU_x86; +#elif __x86_64__ + node->data.root.platform = B_CPU_x86_64; +#else + node->data.root.platform = B_CPU_UNKNOWN; +#endif + break; - switch (cpu->arch.vendor) { - case VENDOR_INTEL: - base = B_CPU_INTEL_x86; + case B_TOPOLOGY_PACKAGE: + node->data.package.vendor = sCPUVendor; + node->data.package.cache_line_size = CACHE_LINE_SIZE; break; - case VENDOR_AMD: - base = B_CPU_AMD_x86; - break; - case VENDOR_CYRIX: - base = B_CPU_CYRIX_x86; - break; - case VENDOR_UMC: - base = B_CPU_INTEL_x86; // XXX - break; - case VENDOR_NEXGEN: - base = B_CPU_INTEL_x86; // XXX - break; - case VENDOR_CENTAUR: - base = B_CPU_VIA_IDT_x86; - break; - case VENDOR_RISE: - base = B_CPU_RISE_x86; - break; - case VENDOR_TRANSMETA: - base = B_CPU_TRANSMETA_x86; - break; - case VENDOR_NSC: - base = B_CPU_NATIONAL_x86; + + case B_TOPOLOGY_CORE: + node->data.core.model = sCPUModel; + node->data.core.default_frequency = sCPUClockSpeed; break; + default: - base = B_CPU_x86; + break; } - - if (base != B_CPU_x86) { - if (base == B_CPU_INTEL_x86 - || (base == B_CPU_AMD_x86 && cpu->arch.family == 0xF)) { - model = (cpu->arch.extended_family << 20) - + (cpu->arch.extended_model << 16) - + (cpu->arch.family << 4) + cpu->arch.model; - } else { - model = (cpu->arch.family << 4) - + cpu->arch.model; - // Isn't much useful extended family and model information - // yet on other processors. - } - } - - sCpuRevision = (cpu->arch.extended_family << 18) - | (cpu->arch.extended_model << 14) | (cpu->arch.type << 12) - | (cpu->arch.family << 8) | (cpu->arch.model << 4) | cpu->arch.stepping; - - sCpuType = base + model; - sCpuClockSpeed = args->arch_args.cpu_clock_speed; - return B_OK; } @@ -164,3 +151,4 @@ _user_get_cpuid(cpuid_info *userInfo, uint32 eaxRegister, uint32 cpuNum) return status; } + diff --git a/src/system/kernel/system_info.cpp b/src/system/kernel/system_info.cpp index d6713b00c0..709fe30860 100644 --- a/src/system/kernel/system_info.cpp +++ b/src/system/kernel/system_info.cpp @@ -1,10 +1,11 @@ /* - * Copyright (c) 2004-2010, Haiku, Inc. + * Copyright (c) 2004-2013, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: * Stefano Ceccherini * Axel Dörfler, axeld@pinc-software.de + * Paweł Dziepak, pdziepak@quarnos.org * Ingo Weinhold, ingo_weinhold@gmx.de */ @@ -16,6 +17,8 @@ #include +#include + #include #include @@ -407,21 +410,14 @@ SystemNotificationService::Listener::OwnerDeleted(AssociatedDataOwner* owner) status_t -_get_system_info(system_info *info, size_t size) +get_system_info(system_info* info) { - if (size != sizeof(system_info)) - return B_BAD_VALUE; - memset(info, 0, sizeof(system_info)); info->boot_time = rtc_boot_time(); info->cpu_count = smp_get_num_cpus(); - for (int32 i = 0; i < info->cpu_count; i++) - info->cpu_infos[i].active_time = cpu_get_active_time(i); - vm_page_get_stats(info); - // TODO: Add page_faults info->used_threads = thread_used_threads(); info->max_threads = thread_max_threads(); @@ -432,17 +428,40 @@ _get_system_info(system_info *info, size_t size) info->used_sems = sem_used_sems(); info->max_sems = sem_max_sems(); + // TODO: fill the new fields + info->kernel_version = kKernelVersion; strlcpy(info->kernel_name, kKernelName, B_FILE_NAME_LENGTH); strlcpy(info->kernel_build_date, __DATE__, B_OS_NAME_LENGTH); strlcpy(info->kernel_build_time, __TIME__, B_OS_NAME_LENGTH); info->abi = B_HAIKU_ABI; - // all other stuff is architecture specific - return arch_get_system_info(info, size); + return B_OK; } +status_t +get_cpu_info(uint32 firstCPU, uint32 cpuCount, cpu_info* info) +{ + if (firstCPU >= (uint32)smp_get_num_cpus()) + return B_BAD_VALUE; + if (cpuCount == 0) + return B_OK; + + uint32 count = std::min(cpuCount, smp_get_num_cpus() - firstCPU); + + memset(info, 0, sizeof(cpu_info) * count); + for (uint32 i = 0; i < count; i++) { + info[i].active_time = cpu_get_active_time(firstCPU + i); + // TODO: cpu_info::load + info[i].enabled = !gCPU[firstCPU + i].disabled; + } + + return B_OK; +} + + + status_t system_info_init(struct kernel_args *args) { @@ -471,15 +490,13 @@ system_notifications_init() status_t -_user_get_system_info(system_info *userInfo, size_t size) +_user_get_system_info(system_info* userInfo) { - // The BeBook says get_system_info() always returns B_OK, - // but that ain't true with invalid addresses if (userInfo == NULL || !IS_USER_ADDRESS(userInfo)) return B_BAD_ADDRESS; system_info info; - status_t status = _get_system_info(&info, size); + status_t status = get_system_info(&info); if (status == B_OK) { if (user_memcpy(userInfo, &info, sizeof(system_info)) < B_OK) return B_BAD_ADDRESS; @@ -491,6 +508,123 @@ _user_get_system_info(system_info *userInfo, size_t size) } +status_t +_user_get_cpu_info(uint32 firstCPU, uint32 cpuCount, cpu_info* userInfo) +{ + if (userInfo == NULL || !IS_USER_ADDRESS(userInfo)) + return B_BAD_ADDRESS; + if (firstCPU >= (uint32)smp_get_num_cpus()) + return B_BAD_VALUE; + if (cpuCount == 0) + return B_OK; + + uint32 count = std::min(cpuCount, smp_get_num_cpus() - firstCPU); + + cpu_info* cpuInfos = new(std::nothrow) cpu_info[count]; + if (cpuInfos == NULL) + return B_NO_MEMORY; + ArrayDeleter _(cpuInfos); + + status_t error = get_cpu_info(firstCPU, count, cpuInfos); + if (error != B_OK) + return error; + + return user_memcpy(userInfo, cpuInfos, sizeof(cpu_info) * count); +} + + +static void +count_topology_nodes(const cpu_topology_node* node, uint32& count) +{ + count++; + for (int32 i = 0; i < node->children_count; i++) + count_topology_nodes(node->children[i], count); +} + + +static int32 +get_logical_processor(const cpu_topology_node* node) +{ + while (node->level != CPU_TOPOLOGY_SMT) { + ASSERT(node->children_count > 0); + node = node->children[0]; + } + + return node->id; +} + + +static cpu_topology_node_info* +generate_topology_array(cpu_topology_node_info* topology, + const cpu_topology_node* node, uint32& count) +{ + if (count == 0) + return topology; + + static const topology_level_type mapTopologyLevels[] = { B_TOPOLOGY_SMT, + B_TOPOLOGY_CORE, B_TOPOLOGY_PACKAGE, B_TOPOLOGY_ROOT }; + + STATIC_ASSERT(sizeof(mapTopologyLevels) / sizeof(topology_level_type) + == CPU_TOPOLOGY_LEVELS + 1); + + topology->id = node->id; + topology->level = node->level; + topology->type = mapTopologyLevels[node->level]; + + arch_fill_topology_node(topology, get_logical_processor(node)); + + count--; + topology++; + for (int32 i = 0; i < node->children_count && count > 0; i++, count--) + topology = generate_topology_array(topology, node->children[i], count); + return topology; +} + + +status_t +_user_get_cpu_topology_info(cpu_topology_node_info* topologyInfos, + uint32* topologyInfoCount) +{ + if (topologyInfoCount == NULL || !IS_USER_ADDRESS(topologyInfoCount)) + return B_BAD_ADDRESS; + + const cpu_topology_node* node = get_cpu_topology(); + + uint32 count = 0; + count_topology_nodes(node, count); + + if (topologyInfos == NULL) + return user_memcpy(topologyInfoCount, &count, sizeof(uint32)); + else if (!IS_USER_ADDRESS(topologyInfoCount)) + return B_BAD_ADDRESS; + + uint32 userCount; + status_t error = user_memcpy(&userCount, topologyInfoCount, sizeof(uint32)); + if (error != B_OK) + return error; + if (userCount == 0) + return B_OK; + count = std::min(count, userCount); + + cpu_topology_node_info* topology + = new(std::nothrow) cpu_topology_node_info[count]; + if (topology == NULL) + return B_NO_MEMORY; + ArrayDeleter _(topology); + memset(topology, 0, sizeof(cpu_topology_node_info) * count); + + uint32 nodesLeft = count; + generate_topology_array(topology, node, nodesLeft); + ASSERT(nodesLeft == 0); + + error = user_memcpy(topologyInfos, topology, + sizeof(cpu_topology_node_info) * count); + if (error != B_OK) + return error; + return user_memcpy(topologyInfoCount, &count, sizeof(uint32)); +} + + status_t _user_get_system_info_etc(int32 id, void* userInfo, size_t size) { diff --git a/src/system/libroot/os/Jamfile b/src/system/libroot/os/Jamfile index ca427584b4..193440898c 100644 --- a/src/system/libroot/os/Jamfile +++ b/src/system/libroot/os/Jamfile @@ -31,7 +31,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { port.c scheduler.c sem.c - system_info.c + system_info.cpp system_revision.c team.c thread.c diff --git a/src/system/libroot/os/system_info.c b/src/system/libroot/os/system_info.c deleted file mode 100644 index 0392337fda..0000000000 --- a/src/system/libroot/os/system_info.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. - * Distributed under the terms of the MIT License. - */ - - -#include - -#include -#include - - -status_t -_get_system_info(system_info *info, size_t size) -{ - if (info == NULL || size != sizeof(system_info)) - return B_BAD_VALUE; - - return _kern_get_system_info(info, size); -} - - -status_t -__get_system_info_etc(int32 id, void *info, size_t size) -{ - if (info == NULL || size == 0 || id < 0) - return B_BAD_VALUE; - - return _kern_get_system_info_etc(id, info, size); -} - - -status_t -__start_watching_system(int32 object, uint32 flags, port_id port, int32 token) -{ - return _kern_start_watching_system(object, flags, port, token); -} - - -status_t -__stop_watching_system(int32 object, uint32 flags, port_id port, int32 token) -{ - return _kern_stop_watching_system(object, flags, port, token); -} - - -int32 -is_computer_on(void) -{ - return _kern_is_computer_on(); -} - - -double -is_computer_on_fire(void) -{ - return 0.63739; -} - diff --git a/src/system/libroot/os/system_info.cpp b/src/system/libroot/os/system_info.cpp new file mode 100644 index 0000000000..adf7a0c710 --- /dev/null +++ b/src/system/libroot/os/system_info.cpp @@ -0,0 +1,242 @@ +/* + * Copyright 2013, Paweł Dziepak, pdziepak@quarnos.org. + * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include + +#include + +#include +#include + + +#if _BEOS_R5_COMPATIBLE_ + + +enum cpu_type { + B_CPU_PPC_601 = 1, + B_CPU_PPC_603 = 2, + B_CPU_PPC_603e = 3, + B_CPU_PPC_604 = 4, + B_CPU_PPC_604e = 5, + B_CPU_PPC_686 = 13, + B_CPU_AMD_29K, + B_CPU_X86, + B_CPU_MC6502, + B_CPU_Z80, + B_CPU_ALPHA, + B_CPU_MIPS, + B_CPU_HPPA, + B_CPU_M68K, + B_CPU_ARM, + B_CPU_SH, + B_CPU_SPARC +}; + +enum platform_type { + B_BEBOX_PLATFORM = 0, + B_MAC_PLATFORM, + B_AT_CLONE_PLATFORM, + B_ENIAC_PLATFORM, + B_APPLE_II_PLATFORM, + B_CRAY_PLATFORM, + B_LISA_PLATFORM, + B_TI_994A_PLATFORM, + B_TIMEX_SINCLAIR_PLATFORM, + B_ORAC_1_PLATFORM, + B_HAL_PLATFORM +}; + +typedef struct { + bigtime_t active_time; /* usec of doing useful work since boot */ +} legacy_cpu_info; + +typedef struct { + int32 id[2]; /* unique machine ID */ + bigtime_t boot_time; /* time of boot (usecs since 1/1/1970) */ + + int32 cpu_count; /* number of cpus */ + enum cpu_type cpu_type; /* type of cpu */ + int32 cpu_revision; /* revision # of cpu */ + legacy_cpu_info cpu_infos[8]; /* info about individual cpus */ + int64 cpu_clock_speed; /* processor clock speed (Hz) */ + int64 bus_clock_speed; /* bus clock speed (Hz) */ + enum platform_type platform_type; /* type of machine we're on */ + + int32 max_pages; /* total # of accessible pages */ + int32 used_pages; /* # of accessible pages in use */ + int32 page_faults; /* # of page faults */ + int32 max_sems; + int32 used_sems; + int32 max_ports; + int32 used_ports; + int32 max_threads; + int32 used_threads; + int32 max_teams; + int32 used_teams; + + char kernel_name[256]; + char kernel_build_date[32]; + char kernel_build_time[32]; + int64 kernel_version; + + bigtime_t _busy_wait_time; /* reserved for whatever */ + + int32 cached_pages; + uint32 abi; /* the system API */ + int32 ignored_pages; /* # of ignored/inaccessible pages */ + int32 pad; +} legacy_system_info; + + +extern "C" status_t +_get_system_info(legacy_system_info* info, size_t size) +{ + if (info == NULL || size != sizeof(legacy_system_info)) + return B_BAD_VALUE; + memset(info, 0, sizeof(legacy_system_info)); + + system_info systemInfo; + status_t error = _kern_get_system_info(&systemInfo); + if (error != B_OK) + return error; + + cpu_info cpuInfos[8]; + error = _kern_get_cpu_info(0, std::min(systemInfo.cpu_count, uint32(8)), + cpuInfos); + if (error != B_OK) + return error; + + info->boot_time = systemInfo.boot_time; + info->cpu_count = std::min(systemInfo.cpu_count, uint32(8)); + for (int32 i = 0; i < info->cpu_count; i++) + info->cpu_infos[i].active_time = cpuInfos[i].active_time; + + info->platform_type = B_AT_CLONE_PLATFORM; + info->cpu_type = B_CPU_X86; + + uint32 topologyNodeCount = 0; + cpu_topology_node_info* topology = NULL; + error = get_cpu_topology_info(NULL, &topologyNodeCount); + if (error != B_OK) + return B_OK; + if (topologyNodeCount != 0) { + topology = new(std::nothrow) cpu_topology_node_info[topologyNodeCount]; + if (topology == NULL) + return B_NO_MEMORY; + } + error = get_cpu_topology_info(topology, &topologyNodeCount); + if (error != B_OK) { + delete[] topology; + return error; + } + + for (uint32 i = 0; i < topologyNodeCount; i++) { + if (topology[i].type == B_TOPOLOGY_CORE) { + info->cpu_clock_speed = topology[i].data.core.default_frequency; + break; + } + } + info->bus_clock_speed = info->cpu_clock_speed; + delete[] topology; + + info->max_pages = std::min(systemInfo.max_pages, uint64(INT32_MAX)); + info->used_pages = std::min(systemInfo.used_pages, uint64(INT32_MAX)); + info->cached_pages = std::min(systemInfo.cached_pages, uint64(INT32_MAX)); + info->ignored_pages = std::min(systemInfo.ignored_pages, uint64(INT32_MAX)); + info->page_faults = std::min(systemInfo.page_faults, uint32(INT32_MAX)); + info->max_sems = std::min(systemInfo.max_sems, uint32(INT32_MAX)); + info->used_sems = std::min(systemInfo.used_sems, uint32(INT32_MAX)); + info->max_ports = std::min(systemInfo.max_ports, uint32(INT32_MAX)); + info->used_ports = std::min(systemInfo.used_ports, uint32(INT32_MAX)); + info->max_threads = std::min(systemInfo.max_threads, uint32(INT32_MAX)); + info->used_threads = std::min(systemInfo.used_threads, uint32(INT32_MAX)); + info->max_teams = std::min(systemInfo.max_teams, uint32(INT32_MAX)); + info->used_teams = std::min(systemInfo.used_teams, uint32(INT32_MAX)); + + strlcpy(info->kernel_name, systemInfo.kernel_name, + sizeof(info->kernel_name)); + strlcpy(info->kernel_build_date, systemInfo.kernel_build_date, + sizeof(info->kernel_build_date)); + strlcpy(info->kernel_build_time, systemInfo.kernel_build_time, + sizeof(info->kernel_build_time)); + info->kernel_version = systemInfo.kernel_version; + + info->abi = systemInfo.abi; + + return B_OK; +} + + +#endif + + +status_t +__get_system_info(system_info* info) +{ + return _kern_get_system_info(info); +} + + +status_t +__get_cpu_info(uint32 firstCPU, uint32 cpuCount, cpu_info* info) +{ + return _kern_get_cpu_info(firstCPU, cpuCount, info); +} + + +status_t +__get_cpu_topology_info(cpu_topology_node_info* topologyInfos, + uint32* topologyInfoCount) +{ + return _kern_get_cpu_topology_info(topologyInfos, topologyInfoCount); +} + + +status_t +__get_system_info_etc(int32 id, void *info, size_t size) +{ + if (info == NULL || size == 0 || id < 0) + return B_BAD_VALUE; + + return _kern_get_system_info_etc(id, info, size); +} + + +status_t +__start_watching_system(int32 object, uint32 flags, port_id port, int32 token) +{ + return _kern_start_watching_system(object, flags, port, token); +} + + +status_t +__stop_watching_system(int32 object, uint32 flags, port_id port, int32 token) +{ + return _kern_stop_watching_system(object, flags, port, token); +} + + +int32 +is_computer_on(void) +{ + return _kern_is_computer_on(); +} + + +double +is_computer_on_fire(void) +{ + return 0.63739; +} + + +B_DEFINE_WEAK_ALIAS(__get_system_info, get_system_info); +B_DEFINE_WEAK_ALIAS(__get_cpu_info, get_cpu_info); +B_DEFINE_WEAK_ALIAS(__get_cpu_topology_info, get_cpu_topology_info); + diff --git a/src/system/libroot/posix/sys/uname.c b/src/system/libroot/posix/sys/uname.c index 120a95157d..18ea62a07a 100644 --- a/src/system/libroot/posix/sys/uname.c +++ b/src/system/libroot/posix/sys/uname.c @@ -20,9 +20,12 @@ int uname(struct utsname *info) { + cpu_topology_node_info root; system_info systemInfo; const char *platform; const char *haikuRevision; + uint32_t count = 1; + status_t error; if (!info) { __set_errno(B_BAD_VALUE); @@ -44,24 +47,20 @@ uname(struct utsname *info) snprintf(info->release, sizeof(info->release), "%" B_PRId64, systemInfo.kernel_version); - // TODO: make this better - switch (systemInfo.platform_type) { - case B_BEBOX_PLATFORM: - platform = "BeBox"; - break; - case B_MAC_PLATFORM: - platform = "BeMac"; - break; - case B_AT_CLONE_PLATFORM: - platform = "BePC"; - break; - case B_64_BIT_PC_PLATFORM: - platform = "x86_64"; - break; - default: - platform = "unknown"; - break; + error = get_cpu_topology_info(&root, &count); + if (error != B_OK || count < 1) + platform = "unknown"; + else { + switch (root.data.root.platform) { + case B_CPU_x86: + platform = "BePC"; + break; + case B_CPU_x86_64: + platform = "x86_64"; + break; + } } + strlcpy(info->machine, platform, sizeof(info->machine)); if (gethostname(info->nodename, sizeof(info->nodename)) != 0)