Mercurial > mplayer.hg
changeset 10885:685c416f12b5
cpuspeed detection for X86 TSC capable CPUs (also added TSC detection, should best be verified by some people with TSC/nonTSC capable CPUs)
author | atmos4 |
---|---|
date | Fri, 19 Sep 2003 23:52:41 +0000 |
parents | bbdaa93c469e |
children | ed0fcc08c988 |
files | cpudetect.c cpudetect.h |
diffstat | 2 files changed, 51 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/cpudetect.c Fri Sep 19 20:44:30 2003 +0000 +++ b/cpudetect.c Fri Sep 19 23:52:41 2003 +0000 @@ -13,6 +13,7 @@ #include <stdio.h> #include <string.h> +#include "osdep/timer.h" #ifdef __NetBSD__ #include <sys/param.h> @@ -119,26 +120,28 @@ do_cpuid(0x00000001, regs2); - tmpstr=GetCpuFriendlyName(regs, regs2); - mp_msg(MSGT_CPUDETECT,MSGL_INFO,"CPU: %s ",tmpstr); - free(tmpstr); - caps->cpuType=(regs2[0] >> 8)&0xf; if(caps->cpuType==0xf){ // use extended family (P4, IA64) caps->cpuType=8+((regs2[0]>>20)&255); } caps->cpuStepping=regs2[0] & 0xf; - mp_msg(MSGT_CPUDETECT,MSGL_INFO,"(Family: %d, Stepping: %d)\n", - caps->cpuType, caps->cpuStepping); // general feature flags: + caps->hasTSC = (regs2[3] & (1 << 8 )) >> 8; // 0x0000010 caps->hasMMX = (regs2[3] & (1 << 23 )) >> 23; // 0x0800000 caps->hasSSE = (regs2[3] & (1 << 25 )) >> 25; // 0x2000000 caps->hasSSE2 = (regs2[3] & (1 << 26 )) >> 26; // 0x4000000 caps->hasMMX2 = caps->hasSSE; // SSE cpus supports mmxext too cl_size = ((regs2[1] >> 8) & 0xFF)*8; if(cl_size) caps->cl_size = cl_size; + + tmpstr=GetCpuFriendlyName(regs, regs2); + mp_msg(MSGT_CPUDETECT,MSGL_INFO,"CPU: %s ",tmpstr); + free(tmpstr); + mp_msg(MSGT_CPUDETECT,MSGL_INFO,"(Family: %d, Stepping: %d)\n", + caps->cpuType, caps->cpuStepping); + } do_cpuid(0x80000000, regs); if (regs[0]>=0x80000001) { @@ -207,6 +210,29 @@ } +static inline unsigned long long int rdtsc( void ) +{ + unsigned long long int retval; + __asm __volatile ("rdtsc":"=A"(retval)::"memory"); + return retval; +} + +/* Returns CPU clock in khz */ +static unsigned int GetCpuSpeed(void) +{ + unsigned long long int tscstart, tscstop; + unsigned int start, stop; + + tscstart = rdtsc(); + start = GetTimer(); + usec_sleep(50000); + stop = GetTimer(); + tscstop = rdtsc(); + + return((tscstop-tscstart)/((stop-start)/1000.0)); +} + + #define CPUID_EXTFAMILY ((regs2[0] >> 20)&0xFF) /* 27..20 */ #define CPUID_EXTMODEL ((regs2[0] >> 16)&0x0F) /* 19..16 */ #define CPUID_TYPE ((regs2[0] >> 12)&0x04) /* 13..12 */ @@ -216,23 +242,37 @@ char *GetCpuFriendlyName(unsigned int regs[], unsigned int regs2[]){ #include "cputable.h" /* get cpuname and cpuvendors */ - char vendor[17]; + char vendor[17], cpuspeed[16]; char *retname; - int i; + int i=0; if (NULL==(retname=(char*)malloc(256))) { mp_msg(MSGT_CPUDETECT,MSGL_FATAL,"Error: GetCpuFriendlyName() not enough memory\n"); exit(1); } + /* Measure CPU speed */ + if (gCpuCaps.hasTSC && (i = GetCpuSpeed()) > 0) { + if (i < 1000000) { + i += 50; /* for rounding */ + snprintf(cpuspeed,15, " %d.%d MHz", i/1000, (i/100)%10); + } else { + i += 500; /* for rounding */ + snprintf(cpuspeed,15, " %d MHz", i/1000); + } + } else { /* No TSC Support */ + cpuspeed[0]='\0'; + } + + sprintf(vendor,"%.4s%.4s%.4s",(char*)(regs+1),(char*)(regs+3),(char*)(regs+2)); for(i=0; i<MAX_VENDORS; i++){ if(!strcmp(cpuvendors[i].string,vendor)){ if(cpuname[i][CPUID_FAMILY][CPUID_MODEL]){ - snprintf(retname,255,"%s %s",cpuvendors[i].name,cpuname[i][CPUID_FAMILY][CPUID_MODEL]); + snprintf(retname,255,"%s %s%s",cpuvendors[i].name,cpuname[i][CPUID_FAMILY][CPUID_MODEL],cpuspeed); } else { - snprintf(retname,255,"unknown %s %d. Generation CPU",cpuvendors[i].name,CPUID_FAMILY); + snprintf(retname,255,"unknown %s %d. Generation CPU%s",cpuvendors[i].name,CPUID_FAMILY,cpuspeed); mp_msg(MSGT_CPUDETECT,MSGL_WARN,"unknown %s CPU:\n",cpuvendors[i].name); mp_msg(MSGT_CPUDETECT,MSGL_WARN,"Vendor: %s\n",cpuvendors[i].string); mp_msg(MSGT_CPUDETECT,MSGL_WARN,"Type: %d\n",CPUID_TYPE);