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);
--- a/cpudetect.h	Fri Sep 19 20:44:30 2003 +0000
+++ b/cpudetect.h	Fri Sep 19 23:52:41 2003 +0000
@@ -18,6 +18,7 @@
 	int isX86;
 	unsigned cl_size; /* size of cache line */
         int hasAltiVec;
+	int hasTSC;
 } CpuCaps;
 
 extern CpuCaps gCpuCaps;