/* Hurd /proc filesystem, implementation of process directories. Copyright (C) 2010 Free Software Foundation, Inc. This file is part of the GNU Hurd. The GNU Hurd is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. The GNU Hurd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "cpuinfo.h" /* This module implements the cpuinfo directory */ /* Helper functions */ #define cpuid(func,ax,bx,cx,dx) __asm__ ("cpuid": "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func)); void cpuinfo_string (char **result, int *result_length, CpuInfo cpuinfo) { int len; char *result_processor; int i = 0; char *tmp_string; cpuinfo_processor_string (&result_processor, cpuinfo, 0); len = asprintf (result, "processor\t: %d\n%s\n", i, result_processor); for (i = 1; i < cpuinfo.cpu_cores; i++) { /* by processor */ cpuinfo_processor_string (&result_processor, cpuinfo, i); tmp_string = *result; len = asprintf (result, "%sprocessor\t: %d\n%s\n", *result, i, result_processor); free (tmp_string); } *result_length = len; } void cpuinfo_processor_string (char **result, CpuInfo cpuinfo, int i) { char *tmp_string; /* by processor */ /* Vendor */ asprintf (result, "vendor_id\t: %s\n", cpuinfo.vendor); /* Model Name */ tmp_string = *result; asprintf (result, "%smodel name\t: %s\n", *result, cpuinfo.model_name); free (tmp_string); /* Core ID */ tmp_string = *result; asprintf (result, "%score id\t\t: %d\n", *result, i); free (tmp_string); /* CPUID LEVEL */ tmp_string = *result; asprintf (result, "%scpuid-level\t: %d\n", *result, cpuinfo.cpuid_level); free (tmp_string); } void debug_cpu (void) { uint32_t func; uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0; uint32_t size = 0; uint32_t i; /* MAX CPUID INSTRUCTION LEVELS */ /* State */ /* EAX 0 http://en.wikipedia.org/wiki/CPUID */ func = 0; cpuid (func, eax, ebx, ecx, edx); size = eax & 0xffff; /* The high-order word is non-zero on some Cyrix CPUs */ for (i = 0; i <= size; i++) { cpuid (i, eax, ebx, ecx, edx); printf ("i %08x a %08x b %08x c %08x d %08x\n", i, eax, ebx, ecx, edx); } /* EAX 0x80000000 http://en.wikipedia.org/wiki/CPUID */ func = 0x80000000; cpuid (func, eax, ebx, ecx, edx); printf ("a %08x b %08x c %08x d %08x\n", eax, ebx, ecx, edx); /* cpuid level */ size = eax; /* The high-order word is non-zero on some Cyrix CPUs */ for (i = 0x80000000; i <= size; i++) { cpuid (i, eax, ebx, ecx, edx); printf ("i %08x a %08x b %08x c %08x d %08x\n", i, eax, ebx, ecx, edx); } /* Brand */ func = 0; cpuid (func, eax, ebx, ecx, edx); switch (ebx) { case 0x756e6547: /* Intel */ printf ("Intel\n"); break; case 0x68747541: /* AMD */ printf ("AMD\n"); break; case 0x69727943: /* Cyrix */ printf ("Cyrix \n"); break; default: printf ("Unknown vendor\n"); break; } } void init_cpuinfo (CpuInfo * cpuinfo) { uint32_t func; uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0; uint32_t tmp; uint32_t size = 0; uint32_t i; int j; char c; /* EAX 0 http://en.wikipedia.org/wiki/CPUID */ func = 0; cpuid (func, eax, ebx, ecx, edx); size = eax & 0xffff; /* The high-order word is non-zero on some Cyrix CPUs */ cpuinfo->cpuid_level = size; /* EAX 0x00000004 http://en.wikipedia.org/wiki/CPUID */ func = 1; cpuid (func, eax, ebx, ecx, edx); cpuinfo->cpu_cores = ebx >> 16 & 0xFF; /* Vendor */ func = 0; cpuid (func, eax, ebx, ecx, edx); i = 0; /* ebx */ tmp = ebx; for (j = 0; j < 4; j++) { c = tmp & 0xff; cpuinfo->vendor[i] = c; tmp = tmp >> 8; i++; } /* edx */ tmp = edx; for (j = 0; j < 4; j++) { c = tmp & 0xff; cpuinfo->vendor[i] = c; tmp = tmp >> 8; i++; } /* ecx */ tmp = ecx; for (j = 0; j < 4; j++) { c = tmp & 0xff; cpuinfo->vendor[i] = c; tmp = tmp >> 8; i++; } cpuinfo->vendor[i] = 0; /* EAX 0x80000002 http://en.wikipedia.org/wiki/CPUID */ /* Model */ i = 0; for (func = 0x80000002; func <= 0x80000004; func++) { cpuid (func, eax, ebx, ecx, edx); /* eax */ tmp = eax; for (j = 0; j < 4; j++) { c = tmp & 0xff; cpuinfo->model_name[i] = c; tmp = tmp >> 8; i++; } /* ebx */ tmp = ebx; for (j = 0; j < 4; j++) { c = tmp & 0xff; cpuinfo->model_name[i] = c; tmp = tmp >> 8; i++; } /* ecx */ tmp = ecx; for (j = 0; j < 4; j++) { c = tmp & 0xff; cpuinfo->model_name[i] = c; tmp = tmp >> 8; i++; } /* edx */ tmp = edx; for (j = 0; j < 4; j++) { c = tmp & 0xff; cpuinfo->model_name[i] = c; tmp = tmp >> 8; i++; } } cpuinfo->model_name[i] = 0; } /* int main (int argc, char *argv[]) { CpuInfo cpuinfo; char *result; int result_length; init_cpuinfo (&cpuinfo); cpuinfo_string (&result, &result_length, cpuinfo); printf ("%d\n%s\n", result_length, result); return 0; } */