mirror of
https://github.com/mpv-player/mpv
synced 2025-03-25 04:38:01 +00:00
cpuspeed detection for X86 TSC capable CPUs (also added TSC detection, should best be verified by some people with TSC/nonTSC capable CPUs)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@10886 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
26afe0c58c
commit
d6825d6349
60
cpudetect.c
60
cpudetect.c
@ -13,6 +13,7 @@ CpuCaps gCpuCaps;
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "osdep/timer.h"
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#include <sys/param.h>
|
||||
@ -119,26 +120,28 @@ void GetCpuCaps( CpuCaps *caps)
|
||||
|
||||
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 @@ void GetCpuCaps( CpuCaps *caps)
|
||||
}
|
||||
|
||||
|
||||
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 @@ void GetCpuCaps( CpuCaps *caps)
|
||||
|
||||
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);
|
||||
|
@ -18,6 +18,7 @@ typedef struct cpucaps_s {
|
||||
int isX86;
|
||||
unsigned cl_size; /* size of cache line */
|
||||
int hasAltiVec;
|
||||
int hasTSC;
|
||||
} CpuCaps;
|
||||
|
||||
extern CpuCaps gCpuCaps;
|
||||
|
Loading…
Reference in New Issue
Block a user