qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 6/6] Pass cpu speed into SM BIOS.


From: Gleb Natapov
Subject: [Qemu-devel] [PATCH 6/6] Pass cpu speed into SM BIOS.
Date: Sun, 24 Aug 2008 14:33:29 +0300
User-agent: StGIT/0.14.2

---

 hw/pc.c |   88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 88 insertions(+), 0 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 03b1b58..a1dd3f4 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -62,6 +62,7 @@ typedef struct _BIOSCfgEntry {
 typedef enum _BIOSCfgEntryNum{
     BIOS_CFG_SIGNATURE,
     BIOS_CFG_UUID,
+    BIOS_CFG_CPUSPEED,
     BIOS_CFG_MAX_ENTRY
 } BIOSCfgEntryNum;
 
@@ -73,6 +74,8 @@ typedef struct _BIOSCfgState {
 
 static BIOSCfgState bios_params;
 
+static uint32_t cpu_speed;
+
 static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
 {
 }
@@ -763,6 +766,89 @@ static int bios_cfg_add_data(BIOSCfgEntryNum entry, 
uint8_t *data, uint16_t len)
     return 1;
 }
 
+
+#ifdef __linux__
+/* get_freq () function is taken from conky source code */
+#define CPUFREQ_PREFIX "/sys/devices/system/cpu"
+#define CPUFREQ_POSTFIX "cpufreq/scaling_cur_freq"
+
+/* return system frequency in MHz (use divisor=1) or GHz (use divisor=1000) */
+static double get_freq(int divisor, unsigned int cpu)
+{
+       FILE *f;
+       char frequency[32];
+       char s[256];
+       double freq = 0;
+
+       if (divisor <= 0)
+               return 0;
+
+       snprintf(s, 256, "%s/cpu%d/%s", CPUFREQ_PREFIX, cpu - 1, 
CPUFREQ_POSTFIX);
+       f = fopen(s, "r");
+       if (f) {
+               /* if there's a cpufreq /sys node, read the current frequency 
from
+                * this node and divide by 1000 to get Mhz. */
+               if (fgets(s, sizeof(s), f)) {
+                       s[strlen(s) - 1] = '\0';
+                       freq = strtod(s, NULL);
+               }
+               fclose(f);
+               return (freq / 1000) / divisor;
+       }
+
+       // open the CPU information file
+       f = fopen("/proc/cpuinfo", "r");
+       if (!f) {
+               perror("Failed to access '/proc/cpuinfo' at get_freq()");
+               return 0;
+       }
+
+       // read the file
+       while (fgets(s, sizeof(s), f) != NULL) {
+
+#if defined(__i386) || defined(__x86_64)
+               // and search for the cpu mhz
+               if (strncmp(s, "cpu MHz", 7) == 0 && cpu == 0) {
+#else
+#if defined(__alpha)
+               // different on alpha
+               if (strncmp(s, "cycle frequency [Hz]", 20) == 0 && cpu == 0) {
+#else
+               // this is different on ppc for some reason
+               if (strncmp(s, "clock", 5) == 0 && cpu == 0) {
+#endif // defined(__alpha)
+#endif // defined(__i386) || defined(__x86_64)
+
+                       // copy just the number
+                       strcpy(frequency, strchr(s, ':') + 2);
+#if defined(__alpha)
+                       // strip " est.\n"
+                       frequency[strlen(frequency) - 6] = '\0';
+                       // kernel reports in Hz
+                       freq = strtod(frequency, NULL) / 1000000;
+#else
+                       // strip \n
+                       frequency[strlen(frequency) - 1] = '\0';
+                       freq = strtod(frequency, NULL);
+#endif
+                       break;
+               }
+               if (strncmp(s, "processor", 9) == 0) {
+                       cpu--;
+                       continue;
+               }
+       }
+
+       fclose(f);
+       return freq / divisor;
+}
+#else
+static double get_freq(int divisor, unsigned int cpu)
+{
+    return 0;
+}
+#endif
+
 /* PC hardware initialisation */
 static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
                      const char *boot_device, DisplayState *ds,
@@ -923,6 +1009,8 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
 
     bios_cfg_add_data(BIOS_CFG_SIGNATURE, "QEMU", 4);
     bios_cfg_add_data(BIOS_CFG_UUID, qemu_uuid, 16);
+    cpu_speed = (uint32_t)get_freq(1, 1);
+    bios_cfg_add_data(BIOS_CFG_CPUSPEED, (uint8_t*)&cpu_speed, 4);
 
     bochs_bios_init();
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]