/* 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. */ /* gcc cpuinfo.c -o cpuinfo `pkg-config --cflags glib-2.0` -lm */ #include "cpuinfo.h" /* This module implements the cpuinfo directory */ /* Helper functions */ #define cpuid(func,ax,bx,cx,dx) __asm__ __volatile__ ("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",*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){ guint32 func; guint32 eax=0,ebx=0,ecx=0,edx=0; guint32 tmp; guint32 size=0; guint32 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) { guint32 func; guint32 eax=0,ebx=0,ecx=0,edx=0; guint32 tmp; guint32 size=0; guint32 i; int j; char c; char *result; int result_length; /* 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; debug_cpu(); init_cpuinfo(&cpuinfo); cpuinfo_string(&result,&result_length,cpuinfo); printf("%d\n%s\n",result_length, result); return 0; }