Browse Source

Add cpu id and cpu frequency functions.

aignacio_sf 18 years ago
parent
commit
601f094d8d

+ 139 - 1
panda/src/display/displayInformation.cxx

@@ -30,6 +30,12 @@ DisplayInformation::
   if (_display_mode_array != NULL) {
     delete _display_mode_array;
   }
+  if (_cpu_id_data != NULL) {
+    delete _cpu_id_data;
+  }
+  if (_cpu_brand_string != NULL) {
+    delete _cpu_brand_string;
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -94,8 +100,20 @@ DisplayInformation() {
 
   _vendor_id = 0;
   _device_id = 0;
-  
+
+  _cpu_id_version = 1;
+  _cpu_id_size = 0;
+  _cpu_id_data = 0;
+
+  _cpu_vendor_string = 0;
+  _cpu_brand_string = 0;
+  _cpu_version_information = 0;
+  _cpu_brand_index = 0;
+
+  _cpu_frequency = 0;
+
   _get_memory_information_function = 0;
+  _cpu_time_function = 0;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -413,3 +431,123 @@ int DisplayInformation::
 get_device_id() {
   return _device_id;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: DisplayInformation::get_cpu_id_version
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+int DisplayInformation::
+get_cpu_id_version() {
+  return _cpu_id_version;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DisplayInformation::get_cpu_id_size
+//       Access: Published
+//  Description: Returns the number of 32-bit values for cpu id 
+//               binary data.
+////////////////////////////////////////////////////////////////////
+int DisplayInformation::
+get_cpu_id_size() {
+  return _cpu_id_size;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DisplayInformation::get_cpu_id_data
+//       Access: Published
+//  Description: Returns part of cpu id binary data based on the 
+//               index.  
+////////////////////////////////////////////////////////////////////
+unsigned int DisplayInformation::
+get_cpu_id_data(int index) {
+  unsigned int data;
+
+  data = 0;
+  if (index >= 0 && index < _cpu_id_size) {
+    data = _cpu_id_data [index];
+  }
+  
+  return data;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DisplayInformation::get_cpu_vendor_string
+//       Access: Published
+//  Description:  
+////////////////////////////////////////////////////////////////////
+char *DisplayInformation::
+get_cpu_vendor_string() {  
+  char *string;
+  
+  string = _cpu_vendor_string;
+  if (string == 0) {
+    string = "";
+  }
+  
+  return string;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DisplayInformation::get_cpu_brand_string
+//       Access: Published
+//  Description:  
+////////////////////////////////////////////////////////////////////
+char *DisplayInformation::
+get_cpu_brand_string() {  
+  char *string;
+  
+  string = _cpu_brand_string;
+  if (string == 0) {
+    string = "";
+  }
+  
+  return string;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DisplayInformation::get_cpu_version_information
+//       Access: Published
+//  Description:  
+////////////////////////////////////////////////////////////////////
+unsigned int DisplayInformation::
+get_cpu_version_information() {  
+  return _cpu_version_information;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DisplayInformation::get_cpu_brand_index
+//       Access: Published
+//  Description:  
+////////////////////////////////////////////////////////////////////
+unsigned int DisplayInformation::
+get_cpu_brand_index() {  
+  return _cpu_brand_index;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DisplayInformation::get_cpu_frequency
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PN_uint64 DisplayInformation::
+get_cpu_frequency() {
+  return _cpu_frequency;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DisplayInformation::get_cpu_time
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PN_uint64 DisplayInformation::
+get_cpu_time() {
+  PN_uint64 cpu_time;
+  
+  cpu_time = 0;
+  if (_cpu_time_function) {
+    cpu_time = _cpu_time_function();
+  }
+  
+  return cpu_time;
+}

+ 24 - 0
panda/src/display/displayInformation.h

@@ -85,6 +85,18 @@ PUBLISHED:
 
   int get_vendor_id();
   int get_device_id();
+
+  int get_cpu_id_version();
+  int get_cpu_id_size();
+  unsigned int get_cpu_id_data(int index);
+
+  char *get_cpu_vendor_string();
+  char *get_cpu_brand_string();
+  unsigned int get_cpu_version_information();
+  unsigned int get_cpu_brand_index();
+  
+  PN_uint64 get_cpu_frequency();
+  PN_uint64 get_cpu_time();
   
 public:
   DetectionState _state;
@@ -116,8 +128,20 @@ public:
 
   int _vendor_id;
   int _device_id;
+
+  int _cpu_id_version;
+  int _cpu_id_size;
+  unsigned int *_cpu_id_data;
+
+  char *_cpu_vendor_string;
+  char *_cpu_brand_string;
+  unsigned int _cpu_version_information;
+  unsigned int _cpu_brand_index;
   
+  PN_uint64 _cpu_frequency;
+    
   void (*_get_memory_information_function) (DisplayInformation *display_information);
+  PN_uint64 (*_cpu_time_function) (void);
 };
 
 #endif

+ 638 - 1
panda/src/windisplay/winGraphicsPipe.cxx

@@ -100,6 +100,547 @@ void get_memory_information (DisplayInformation *display_information)
   }  
 }
 
+typedef union
+{
+  PN_uint64 long_integer;
+}
+LONG_INTEGER;
+
+PN_uint64 cpu_time_function (void) {
+  LONG_INTEGER long_integer;
+  LONG_INTEGER *long_integer_pointer;
+  
+  long_integer_pointer = &long_integer;
+  
+  __asm
+  {
+      mov   ebx,[long_integer_pointer]
+      rdtsc
+      mov   [ebx + 0], eax
+      mov   [ebx + 4], edx
+  }
+
+  return long_integer.long_integer;
+}
+
+typedef union
+{
+  struct
+  {
+    union
+    {
+      struct
+      {
+        unsigned char al;
+        unsigned char ah;
+      };
+      unsigned int eax;
+    };
+    unsigned int ebx;
+    unsigned int ecx;
+    unsigned int edx;
+  };
+}
+CPU_ID_REGISTERS;
+
+typedef struct
+{
+  union
+  {
+    struct
+    {
+      int maximum_cpu_id_input;
+      char cpu_vendor [16];
+    };
+
+    CPU_ID_REGISTERS cpu_id_registers_0;
+  };
+
+  union
+  {
+    CPU_ID_REGISTERS cpu_id_registers_1;
+
+    struct
+    {
+      // eax
+      union
+      {
+        unsigned int eax;
+        unsigned int version_information;
+        struct
+        {
+          unsigned int stepping_id : 4;
+          unsigned int model : 4;
+          unsigned int family : 4;
+          unsigned int processor_type : 2;
+          unsigned int reserved_0 : 2;
+          unsigned int extended_model_id : 4;
+          unsigned int extended_family_id : 8;
+          unsigned int reserved_1 : 4;
+        };
+      };
+
+      // ebx
+      union
+      {
+        unsigned int ebx;
+        struct
+        {
+          unsigned int brand_index : 8;
+          unsigned int clflush : 8;
+          unsigned int maximum_logical_processors : 8;
+          unsigned int initial_apic_id : 8;
+        };
+      };
+
+      // ecx
+      union
+      {
+        unsigned int ecx;
+        struct
+        {
+          unsigned int sse3 : 1;
+          unsigned int reserved_1_to_2 : 2;
+          unsigned int monitor : 1;
+          unsigned int ds_cpl : 1;
+          unsigned int vmx : 1;
+          unsigned int reserved_6 : 1;
+          unsigned int est : 1;
+          unsigned int tm2 : 1;
+          unsigned int reserved_9 : 1;
+          unsigned int cnxt_id : 1;
+          unsigned int reserved_11_to_12 : 2;
+          unsigned int cmpxchg16b : 1;
+          unsigned int xtpr_disable : 1;
+          unsigned int reserved_15_to_31 : 17;
+        };
+      };
+
+      // edx
+      union
+      {
+        unsigned int edx;
+        struct
+        {
+          unsigned int fpu : 1;
+          unsigned int vme : 1;
+          unsigned int de : 1;
+          unsigned int pse : 1;
+          unsigned int tsc : 1;
+          unsigned int msr : 1;
+          unsigned int pae : 1;
+          unsigned int mce : 1;
+          unsigned int cx8 : 1;
+          unsigned int apic : 1;
+          unsigned int reserved_10 : 1;
+          unsigned int sep : 1;
+          unsigned int mtrr : 1;
+          unsigned int pge : 1;
+          unsigned int mca : 1;
+          unsigned int cmov : 1;
+          unsigned int pat : 1;
+          unsigned int pse_36 : 1;
+          unsigned int psn : 1;
+          unsigned int cflush : 1;
+          unsigned int reserved_20 : 1;
+          unsigned int ds : 1;
+          unsigned int acpi : 1;
+          unsigned int mmx : 1;
+          unsigned int fxsr : 1;
+          unsigned int sse : 1;
+          unsigned int sse2 : 1;
+          unsigned int ss : 1;
+          unsigned int htt : 1;
+          unsigned int tm : 1;
+          unsigned int reserved_30 : 1;
+          unsigned int pbe : 1;
+        };
+      };
+    };
+  };
+
+  #define MAXIMUM_2 8
+  #define MAXIMUM_CHARACTERS (MAXIMUM_2 * sizeof (CPU_ID_REGISTERS))
+
+  union
+  {
+    CPU_ID_REGISTERS cpu_id_registers_2;
+    unsigned char character_array_2 [MAXIMUM_CHARACTERS];
+    CPU_ID_REGISTERS cpu_id_registers_2_array [MAXIMUM_2];
+  };
+
+  union
+  {
+    CPU_ID_REGISTERS cpu_id_registers_0x80000000;
+  };
+
+  union
+  {
+    CPU_ID_REGISTERS cpu_id_registers_0x80000001;
+  };
+
+  union
+  {
+    char cpu_brand_string [sizeof (CPU_ID_REGISTERS) * 3];
+    struct 
+    {
+      CPU_ID_REGISTERS cpu_id_registers_0x80000002;
+      CPU_ID_REGISTERS cpu_id_registers_0x80000003;
+      CPU_ID_REGISTERS cpu_id_registers_0x80000004;
+    };
+  };
+
+  union
+  {
+    struct
+    {
+      // eax
+      union
+      {
+        unsigned int eax;
+      };
+
+      // ebx
+      union
+      {
+        unsigned int ebx;
+      };
+
+      // ecx
+      union
+      {
+        unsigned int ecx;
+        struct
+        {
+          unsigned int l1_data_cache_line_size : 8;
+          unsigned int l1_data_reserved_8_to_15 : 8;
+          unsigned int l1_data_associativity : 8;
+          unsigned int l1_data_cache_size : 8;
+        };
+      };
+
+      // edx
+      union
+      {
+        unsigned int edx;
+        struct
+        {
+          unsigned int l1_code_cache_line_size : 8;
+          unsigned int l1_code_reserved_8_to_15 : 8;
+          unsigned int l1_code_associativity : 8;
+          unsigned int l1_code_cache_size : 8;
+        };
+      };
+    };
+    CPU_ID_REGISTERS cpu_id_registers_0x80000005;
+  };
+
+  union
+  {
+    struct
+    {
+      // eax
+      union
+      {
+        unsigned int eax;
+      };
+
+      // ebx
+      union
+      {
+        unsigned int ebx;
+      };
+
+      // ecx
+      union
+      {
+        unsigned int ecx;
+        struct
+        {
+          unsigned int l2_cache_line_size : 8;
+          unsigned int l2_reserved_8_to_11 : 4;
+          unsigned int l2_associativity : 4;
+          unsigned int l2_cache_size : 16;
+        };
+      };
+
+      // edx
+      union
+      {
+        unsigned int edx;
+      };
+    };
+    CPU_ID_REGISTERS cpu_id_registers_0x80000006;
+  };
+
+  union
+  {
+    struct
+    {
+      // eax
+      union
+      {
+        unsigned int eax;
+      };
+
+      // ebx
+      union
+      {
+        unsigned int ebx;
+      };
+
+      // ecx
+      union
+      {
+        unsigned int ecx;
+      };
+
+      // edx
+      union
+      {
+        unsigned int edx;
+      };
+    };
+    CPU_ID_REGISTERS cpu_id_registers_0x80000008;
+  };
+  
+  unsigned int cache_line_size;
+  unsigned int log_base_2_cache_line_size;
+}
+CPU_ID;
+
+typedef struct
+{
+  CPU_ID_REGISTERS cpu_id_registers_0;
+  CPU_ID_REGISTERS cpu_id_registers_1;
+
+  CPU_ID_REGISTERS cpu_id_registers_0x80000000;
+  CPU_ID_REGISTERS cpu_id_registers_0x80000001;
+  CPU_ID_REGISTERS cpu_id_registers_0x80000002;
+  CPU_ID_REGISTERS cpu_id_registers_0x80000003;
+  CPU_ID_REGISTERS cpu_id_registers_0x80000004;
+
+  CPU_ID_REGISTERS cpu_id_registers_0x80000006;
+
+  CPU_ID_REGISTERS cpu_id_registers_0x80000008;
+}
+CPU_ID_BINARY_DATA;
+
+typedef struct
+{
+  union
+  {
+    CPU_ID_BINARY_DATA cpu_binary_data;
+    unsigned int data_array [sizeof (CPU_ID_BINARY_DATA) / 4];
+  };
+}
+CPU_ID_BINARY_DATA_ARRAY;
+
+void cpu_id_to_cpu_id_binary_data (CPU_ID *cpu_id, CPU_ID_BINARY_DATA *cpu_id_binary_data) {
+
+  cpu_id_binary_data -> cpu_id_registers_0 = cpu_id -> cpu_id_registers_0;
+  cpu_id_binary_data -> cpu_id_registers_1 = cpu_id -> cpu_id_registers_1;
+  cpu_id_binary_data -> cpu_id_registers_0x80000000 = cpu_id -> cpu_id_registers_0x80000000;
+  cpu_id_binary_data -> cpu_id_registers_0x80000001 = cpu_id -> cpu_id_registers_0x80000001;
+  cpu_id_binary_data -> cpu_id_registers_0x80000002 = cpu_id -> cpu_id_registers_0x80000002;
+  cpu_id_binary_data -> cpu_id_registers_0x80000003 = cpu_id -> cpu_id_registers_0x80000003;
+  cpu_id_binary_data -> cpu_id_registers_0x80000004 = cpu_id -> cpu_id_registers_0x80000004;
+  cpu_id_binary_data -> cpu_id_registers_0x80000006 = cpu_id -> cpu_id_registers_0x80000006;
+  cpu_id_binary_data -> cpu_id_registers_0x80000008 = cpu_id -> cpu_id_registers_0x80000008;
+}
+
+void cpu_id_binary_data_to_cpu_id (CPU_ID_BINARY_DATA *cpu_id_binary_data, CPU_ID *cpu_id) {
+
+  memset (cpu_id, 0, sizeof (CPU_ID));
+
+  cpu_id -> cpu_id_registers_0 = cpu_id_binary_data -> cpu_id_registers_0;
+  cpu_id -> cpu_id_registers_1 = cpu_id_binary_data -> cpu_id_registers_1;
+  cpu_id -> cpu_id_registers_0x80000000 = cpu_id_binary_data -> cpu_id_registers_0x80000000;
+  cpu_id -> cpu_id_registers_0x80000001 = cpu_id_binary_data -> cpu_id_registers_0x80000001;
+  cpu_id -> cpu_id_registers_0x80000002 = cpu_id_binary_data -> cpu_id_registers_0x80000002;
+  cpu_id -> cpu_id_registers_0x80000003 = cpu_id_binary_data -> cpu_id_registers_0x80000003;
+  cpu_id -> cpu_id_registers_0x80000004 = cpu_id_binary_data -> cpu_id_registers_0x80000004;
+  cpu_id -> cpu_id_registers_0x80000006 = cpu_id_binary_data -> cpu_id_registers_0x80000006;
+  cpu_id -> cpu_id_registers_0x80000008 = cpu_id_binary_data -> cpu_id_registers_0x80000008;
+}
+
+int cpuid (int input_eax, CPU_ID_REGISTERS *cpu_id_registers) {
+  int state;
+
+  state = false;   
+  __try
+  {
+    if (input_eax == 0) {
+      // the order of ecx and edx is swapped when saved to make a proper vendor string
+      __asm
+      {
+          mov   eax, [input_eax]
+          mov   edi, [cpu_id_registers]
+
+          cpuid
+
+          mov   [edi + 0], eax
+          mov   [edi + 4], ebx
+          mov   [edi + 8], edx
+          mov   [edi + 12], ecx
+      }
+    }
+    else {
+      __asm
+      {
+          mov   eax, [input_eax]
+          mov   edi, [cpu_id_registers]
+
+          cpuid
+
+          mov   [edi + 0], eax
+          mov   [edi + 4], ebx
+          mov   [edi + 8], ecx
+          mov   [edi + 12], edx
+      }
+    }
+
+    state = true;
+  }
+  __except (1)
+  {
+    state = false;
+  }
+
+  return state;
+}
+
+void parse_cpu_id (CPU_ID *cpu_id) {
+
+  printf ("CPUID\n");
+  printf ("  vendor = %s \n", cpu_id -> cpu_vendor);
+  printf ("  brand string %s \n", cpu_id -> cpu_brand_string);
+  printf ("  maximum_cpu_id_input = %u \n", cpu_id -> maximum_cpu_id_input);
+  printf ("  maximum extended information = 0x%X \n", cpu_id -> cpu_id_registers_0x80000000.eax);  
+
+  printf ("  MMX  = %u \n", cpu_id -> mmx);
+  printf ("  SSE  = %u \n", cpu_id -> sse);
+  printf ("  SSE2 = %u \n", cpu_id -> sse2);
+  printf ("  SSE3 = %u \n", cpu_id -> sse3);
+
+  printf ("  EST  = %u \n", cpu_id -> est);
+
+  if (cpu_id -> maximum_cpu_id_input >= 1) {
+    printf ("  version_information \n");
+    printf ("    stepping_id %u \n", cpu_id -> stepping_id);
+    printf ("    model %u \n", cpu_id -> model);
+    printf ("    family %u \n", cpu_id -> family);
+    printf ("    processor_type %u \n", cpu_id -> processor_type);
+    printf ("    extended_model_id %u \n", cpu_id -> extended_model_id);
+    printf ("    extended_family_id %u \n", cpu_id -> extended_family_id);
+
+    printf ("    brand_index %u \n", cpu_id -> brand_index);
+    printf ("    clflush %u \n", cpu_id -> clflush);
+    printf ("    maximum_logical_processors %u \n", cpu_id -> maximum_logical_processors);
+    printf ("    initial_apic_id %u \n", cpu_id -> initial_apic_id);
+
+//    printf ("  cache_line_size %u \n", cpu_id -> cache_line_size);
+//    printf ("  log_base_2_cache_line_size %u \n", cpu_id -> log_base_2_cache_line_size);
+  }
+
+  if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000005) {
+    printf ("  l1_data_cache_line_size %d \n", cpu_id -> l1_data_cache_line_size);
+    printf ("  l1_data_associativity %d \n", cpu_id -> l1_data_associativity);
+    printf ("  l1_data_cache_size %dK \n", cpu_id -> l1_data_cache_size);       
+
+    printf ("  l1_code_cache_line_size %d \n", cpu_id -> l1_code_cache_line_size);
+    printf ("  l1_code_associativity %d \n", cpu_id -> l1_code_associativity);
+    printf ("  l1_code_cache_size %dK \n", cpu_id -> l1_code_cache_size);
+  }
+
+  if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000006) {
+    printf ("  l2_cache_line_size %d \n", cpu_id -> l2_cache_line_size);
+    printf ("  l2_associativity %d \n", cpu_id -> l2_associativity);
+    printf ("  l2_cache_size %dK \n", cpu_id -> l2_cache_size);       
+  }
+}
+
+int initialize_cpu_id (CPU_ID *cpu_id) {
+
+  int state;
+  int debug;
+  
+  state = false;
+  debug = false;
+  memset (cpu_id, 0, sizeof (CPU_ID));
+
+  if (cpuid (0, &cpu_id -> cpu_id_registers_0)) {
+    if (cpu_id -> maximum_cpu_id_input >= 1) {
+      cpuid (1, &cpu_id -> cpu_id_registers_1);
+    }
+    if (cpu_id -> maximum_cpu_id_input >= 2) {
+      unsigned int index;
+
+      cpuid (2, &cpu_id -> cpu_id_registers_2);
+      if (debug) {
+        printf ("  al = %u \n", cpu_id -> cpu_id_registers_2.al);
+      }
+      
+      for (index = 1; index < cpu_id -> cpu_id_registers_2.al && index < MAXIMUM_2; index++) {
+        cpuid (2, &cpu_id -> cpu_id_registers_2_array [index]);
+      }
+
+      for (index = 1; index < MAXIMUM_CHARACTERS; index++) {
+        if (cpu_id -> character_array_2 [index]) {
+          if (debug) {
+            printf ("  cache/TLB byte = %X \n", cpu_id -> character_array_2 [index]);
+          }
+          switch (cpu_id -> character_array_2 [index])
+          {
+            case 0x0A:
+            case 0x0C:
+              cpu_id -> cache_line_size = 32;
+              cpu_id -> log_base_2_cache_line_size = 5;
+              break;
+
+            case 0x2C:
+            case 0x60:
+            case 0x66:
+            case 0x67:
+            case 0x68:
+              cpu_id -> cache_line_size = 64;
+              cpu_id -> log_base_2_cache_line_size = 6;
+              break;
+          }
+        }
+      }
+    }
+
+    cpuid (0x80000000, &cpu_id -> cpu_id_registers_0x80000000);  
+
+    if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000001) {
+      cpuid (0x80000001, &cpu_id -> cpu_id_registers_0x80000001);  
+    }
+    
+    if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000004) {
+      cpuid (0x80000002, &cpu_id -> cpu_id_registers_0x80000002);  
+      cpuid (0x80000003, &cpu_id -> cpu_id_registers_0x80000003);  
+      cpuid (0x80000004, &cpu_id -> cpu_id_registers_0x80000004);  
+    }
+
+    if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000005) {
+      cpuid (0x80000005, &cpu_id -> cpu_id_registers_0x80000005);  
+    }
+
+    if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000006) {
+      cpuid (0x80000006, &cpu_id -> cpu_id_registers_0x80000006);  
+    }
+
+    if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000008) {
+      cpuid (0x80000008, &cpu_id -> cpu_id_registers_0x80000008);  
+    }    
+
+    state = true;
+  }
+  
+  return state;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: WinGraphicsPipe::Constructor
 //       Access: Public
@@ -109,6 +650,7 @@ WinGraphicsPipe::
 WinGraphicsPipe() {
 
   bool state;
+  char string [512];
   
   state = false;
   _supported_types = OT_window | OT_fullscreen_window;
@@ -141,9 +683,104 @@ WinGraphicsPipe() {
     state = true;    
   }
 #endif
-
+  
   // set callback for memory function
   _display_information -> _get_memory_information_function = get_memory_information;
+
+  // set callback for cpu time function
+  _display_information -> _cpu_time_function = cpu_time_function;
+
+  // determine CPU frequency
+  PN_uint64 time;
+  PN_uint64 end_time;
+  LARGE_INTEGER counter;
+  LARGE_INTEGER end;
+  LARGE_INTEGER frequency;
+
+  time = 0;
+  end_time = 0;
+  counter.QuadPart = 0;
+  end.QuadPart = 0;
+  frequency.QuadPart = 0;
+  
+  int priority;
+  HANDLE thread;
+
+  windisplay_cat.info() << "begin QueryPerformanceFrequency\n";
+    
+  thread = GetCurrentThread();
+  priority = GetThreadPriority (thread);
+  SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL);
+  
+  if (QueryPerformanceFrequency(&frequency)) {    
+    if (frequency.QuadPart > 0) {
+      if (QueryPerformanceCounter (&counter)) {
+        time = cpu_time_function();
+        end.QuadPart = counter.QuadPart + frequency.QuadPart;
+        while (QueryPerformanceCounter (&counter) && counter.QuadPart < end.QuadPart) {
+
+        }
+        end_time = cpu_time_function();
+
+        _display_information -> _cpu_frequency = end_time - time;
+      }
+    }
+  }
+
+  SetThreadPriority(thread, priority);
+      
+  sprintf (string, "QueryPerformanceFrequency: %I64d\n", frequency.QuadPart);    
+  windisplay_cat.info() << string;
+  sprintf (string, "CPU frequency: %I64d\n", _display_information -> _cpu_frequency);
+  windisplay_cat.info() << string;
+
+  // CPUID
+  int debug;
+  CPU_ID cpu_id;
+
+  debug = false;
+  
+  windisplay_cat.info() << "start CPU ID\n";
+  
+  if (initialize_cpu_id (&cpu_id)) {  
+    CPU_ID_BINARY_DATA *cpu_id_binary_data;
+    
+    cpu_id_binary_data = new (CPU_ID_BINARY_DATA);    
+    if (cpu_id_binary_data) {  
+      cpu_id_to_cpu_id_binary_data (&cpu_id, cpu_id_binary_data);
+      _display_information -> _cpu_id_size = sizeof (CPU_ID_BINARY_DATA) / sizeof (unsigned int);
+      _display_information -> _cpu_id_data = (unsigned int *) cpu_id_binary_data;
+
+      _display_information -> _cpu_vendor_string = strdup(cpu_id.cpu_vendor);
+      _display_information -> _cpu_brand_string = strdup(cpu_id.cpu_brand_string);
+      _display_information -> _cpu_version_information = cpu_id.version_information;
+      _display_information -> _cpu_brand_index = cpu_id.brand_index;
+
+      if (debug) {
+        printf ("%X|", _display_information -> _cpu_id_version);
+
+        int index;
+        for (index = 0; index < _display_information -> _cpu_id_size; index++) {
+          unsigned int data;
+
+          data = _display_information -> _cpu_id_data [index];
+
+          printf ("%X", data);
+          if (index < (_display_information -> _cpu_id_size - 1))
+          {
+            printf ("|");        
+          }
+        }
+        printf ("\n");
+      }
+    }
+
+    if (debug) {
+      parse_cpu_id (&cpu_id);
+    }
+  }
+
+  windisplay_cat.info() << "end CPU ID\n";
   
   if (state) {