diff options
Diffstat (limited to 'arch/linux/x86/processor.h')
-rw-r--r-- | arch/linux/x86/processor.h | 182 |
1 files changed, 175 insertions, 7 deletions
diff --git a/arch/linux/x86/processor.h b/arch/linux/x86/processor.h index fd8711af..97fa4555 100644 --- a/arch/linux/x86/processor.h +++ b/arch/linux/x86/processor.h @@ -1,6 +1,6 @@ /* * HardInfo - Displays System Information - * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.br> + * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +typedef struct _ProcessorCache ProcessorCache; + +struct _ProcessorCache { + gint level; + gint number_of_sets; + gint physical_line_partition; + gint size; + gchar *type; + gint ways_of_associativity; +}; + struct _Processor { gchar *model_name; gchar *vendor_id; @@ -30,6 +41,8 @@ struct _Processor { gchar *strmodel; gint id; + + GSList *cache; }; /* @@ -148,12 +161,91 @@ static void get_processor_strfamily(Processor * processor) } } +static gchar *__cache_get_info_as_string(Processor *processor) +{ + gchar *result = g_strdup(""); + GSList *cache_list; + ProcessorCache *cache; + + if (!processor->cache) { + return g_strdup("Cache information not available=\n"); + } + + for (cache_list = processor->cache; cache_list; cache_list = cache_list->next) { + cache = (ProcessorCache *)cache_list->data; + + result = h_strdup_cprintf("Level %d (%s)=%d-way set-associative, %d sets, %dKB size\n", + result, + cache->level, + cache->type, + cache->ways_of_associativity, + cache->number_of_sets, + cache->size); + } + + return result; +} + +static void __cache_obtain_info(Processor *processor, gint processor_number) +{ + ProcessorCache *cache; + gchar *endpoint, *entry, *index; + gint i; + + endpoint = g_strdup_printf("/sys/devices/system/cpu/cpu%d/cache", processor_number); + + for (i = 0; ; i++) { + cache = g_new0(ProcessorCache, 1); + + index = g_strdup_printf("index%d/", i); + + entry = g_strconcat(index, "type", NULL); + cache->type = h_sysfs_read_string(endpoint, entry); + g_free(entry); + + if (!cache->type) { + g_free(cache); + g_free(index); + goto fail; + } + + entry = g_strconcat(index, "level", NULL); + cache->level = h_sysfs_read_int(endpoint, entry); + g_free(entry); + + entry = g_strconcat(index, "number_of_sets", NULL); + cache->number_of_sets = h_sysfs_read_int(endpoint, entry); + g_free(entry); + + entry = g_strconcat(index, "physical_line_partition", NULL); + cache->physical_line_partition = h_sysfs_read_int(endpoint, entry); + g_free(entry); + + entry = g_strconcat(index, "size", NULL); + cache->size = h_sysfs_read_int(endpoint, entry); + g_free(entry); + + + entry = g_strconcat(index, "ways_of_associativity", NULL); + cache->ways_of_associativity = h_sysfs_read_int(endpoint, entry); + g_free(entry); + + g_free(index); + + processor->cache = g_slist_append(processor->cache, cache); + } + +fail: + g_free(endpoint); +} + static GSList *__scan_processors(void) { GSList *procs = NULL; Processor *processor = NULL; FILE *cpuinfo; gchar buffer[256]; + gint processor_number = 0; cpuinfo = fopen("/proc/cpuinfo", "r"); if (!cpuinfo) @@ -169,6 +261,8 @@ static GSList *__scan_processors(void) } processor = g_new0(Processor, 1); + + __cache_obtain_info(processor, processor_number++); } if (tmp[0] && tmp[1]) { @@ -208,6 +302,12 @@ static GSList *__scan_processors(void) return procs; } +/* + * Sources: + * - Linux' cpufeature.h + * - http://gentoo-wiki.com/Cpuinfo + * - Intel IA-32 Architecture Software Development Manual + */ static struct { char *name, *meaning; } flag_meaning[] = { @@ -254,6 +354,68 @@ static struct { { "tm", "Thermal Monitor" }, { "pbe", "Pending Break Enable" }, { "pb", "Pending Break Enable" }, + { "pn", "Processor serial number" }, + { "ds", "Debug Store" }, + { "xmm2", "Streaming SIMD Extensions-2" }, + { "xmm3", "Streaming SIMD Extensions-3" }, + { "selfsnoop", "CPU self snoop" }, + { "rdtscp", "RDTSCP" }, + { "recovery", "CPU in recovery mode" }, + { "longrun", "Longrun power control" }, + { "lrti", "LongRun table interface" }, + { "cxmmx", "Cyrix MMX extensions" }, + { "k6_mtrr", "AMD K6 nonstandard MTRRs" }, + { "cyrix_arr", "Cyrix ARRs (= MTRRs)" }, + { "centaur_mcr","Centaur MCRs (= MTRRs)" }, + { "constant_tsc","TSC ticks at a constant rate" }, + { "up", "smp kernel running on up" }, + { "fxsave_leak","FXSAVE leaks FOP/FIP/FOP" }, + { "arch_perfmon","Intel Architectural PerfMon" }, + { "pebs", "Precise-Event Based Sampling" }, + { "bts", "Branch Trace Store" }, + { "sync_rdtsc", "RDTSC synchronizes the CPU" }, + { "rep_good", "rep microcode works well on this CPU" }, + { "mwait", "Monitor/Mwait support" }, + { "ds_cpl", "CPL Qualified Debug Store" }, + { "est", "Enhanced SpeedStep" }, + { "tm2", "Thermal Monitor 2" }, + { "cid", "Context ID" }, + { "xtpr", "Send Task Priority Messages" }, + { "xstore", "on-CPU RNG present (xstore insn)" }, + { "xstore_en", "on-CPU RNG enabled" }, + { "xcrypt", "on-CPU crypto (xcrypt insn)" }, + { "xcrypt_en", "on-CPU crypto enabled" }, + { "ace2", "Advanced Cryptography Engine v2" }, + { "ace2_en", "ACE v2 enabled" }, + { "phe", "PadLock Hash Engine" }, + { "phe_en", "PHE enabled" }, + { "pmm", "PadLock Montgomery Multiplier" }, + { "pmm_en", "PMM enabled" }, + { "lahf_lm", "LAHF/SAHF in long mode" }, + { "cmp_legacy", "HyperThreading not valid" }, + { "lm", "LAHF/SAHF in long mode" }, + { "ds_cpl", "CPL Qualified Debug Store" }, + { "vmx", "Virtualization support (Intel)" }, + { "svm", "Virtualization support (AMD)" }, + { "est", "Enhanced SpeedStep" }, + { "tm2", "Thermal Monitor 2" }, + { "ssse3", "Supplemental Streaming SIMD Extension 3" }, + { "cx16", "CMPXCHG16B instruction" }, + { "xptr", "Send Task Priority Messages" }, + { "pebs", "Precise Event Based Sampling" }, + { "bts", "Branch Trace Store" }, + { "ida", "Intel Dynamic Acceleration" }, + { "arch_perfmon","Intel Architectural PerfMon" }, + { "pni", "Streaming SIMD Extension 3 (Prescott New Instruction)" }, + { "rep_good", "rep microcode works well on this CPU" }, + { "ts", "Thermal Sensor" }, + { "sse3", "Streaming SIMD Extension 3" }, + { "sse4", "Streaming SIMD Extension 4" }, + { "tni", "Tejas New Instruction" }, + { "nni", "Nehalem New Instruction" }, + { "tpr", "Task Priority Register" }, + { "vid", "Voltage Identifier" }, + { "fid", "Frequency Identifier" }, { NULL, NULL }, }; @@ -289,9 +451,11 @@ gchar *processor_get_capabilities_from_flags(gchar * strflags) static gchar *processor_get_detailed_info(Processor * processor) { - gchar *tmp, *ret; + gchar *tmp, *ret, *cache_info; tmp = processor_get_capabilities_from_flags(processor->flags); + cache_info = __cache_get_info_as_string(processor); + ret = g_strdup_printf("[Processor]\n" "Name=%s\n" "Family, model, stepping=%d, %d, %d (%s)\n" @@ -307,6 +471,8 @@ static gchar *processor_get_detailed_info(Processor * processor) "F00F Bug=%s\n" "Coma Bug=%s\n" "Has FPU=%s\n" + "[Cache]\n" + "%s\n" "[Capabilities]\n" "%s", processor->model_name, @@ -322,15 +488,17 @@ static gchar *processor_get_detailed_info(Processor * processor) #else "Big Endian", #endif - processor->bug_fdiv ? processor->bug_fdiv : "yes", - processor->bug_hlt ? processor->bug_hlt : "yes", - processor->bug_f00f ? processor->bug_f00f : "yes", - processor->bug_coma ? processor->bug_coma : "yes", + processor->bug_fdiv ? processor->bug_fdiv : "no", + processor->bug_hlt ? processor->bug_hlt : "no", + processor->bug_f00f ? processor->bug_f00f : "no", + processor->bug_coma ? processor->bug_coma : "no", processor->has_fpu ? processor->has_fpu : "no", + cache_info, tmp); g_free(tmp); + g_free(cache_info); + return ret; - } static gchar *processor_get_info(GSList * processors) |