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

[Xen-changelog] [xen-unstable] hvmloader: Properly implement some more SMBIOS fields.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1207066865 -3600
# Node ID 69c951243105e9490c10bd9faeacc4725bf6b65f
# Parent  db943e8d10514445763123bb56b383e795e9b518
hvmloader: Properly implement some more SMBIOS fields.

In particular:
 - BIOS release date
 - BIOS characteristics
 - BIOS extended characteristics (Targeted Content Distribution is
   required to be specified to pass WHQL).
 - CPU speed

Based on a patch by Kamala Narasimhan <kamala.narasimhan@xxxxxxxxxx>

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 tools/firmware/hvmloader/Makefile    |   15 ++++++---
 tools/firmware/hvmloader/hvmloader.c |    2 +
 tools/firmware/hvmloader/smbios.c    |   57 +++++++++++++++++++++++++----------
 tools/firmware/hvmloader/util.c      |   53 ++++++++++++++++++++++++++++++++
 tools/firmware/hvmloader/util.h      |   48 ++++++++++++++++++++++++++++-
 5 files changed, 152 insertions(+), 23 deletions(-)

diff -r db943e8d1051 -r 69c951243105 tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Tue Apr 01 10:09:33 2008 +0100
+++ b/tools/firmware/hvmloader/Makefile Tue Apr 01 17:21:05 2008 +0100
@@ -42,16 +42,21 @@ OBJS = $(patsubst %.c,%.o,$(SRCS))
 .PHONY: all
 all: hvmloader
 
-hvmloader: roms.h subdirs-all $(SRCS)
-       $(CC) $(CFLAGS) -c $(SRCS)
-       $(LD) $(LDFLAGS_DIRECT) -N -Ttext $(LOADADDR) -o hvmloader.tmp $(OBJS) 
acpi/acpi.a
+smbios.o: CFLAGS += -D__SMBIOS_DATE__="\"$(shell date +%m/%d/%Y)\""
+
+hvmloader: roms.h subdirs-all $(OBJS)
+       $(LD) $(LDFLAGS_DIRECT) -N -Ttext $(LOADADDR) \
+               -o hvmloader.tmp $(OBJS) acpi/acpi.a
        $(OBJCOPY) hvmloader.tmp hvmloader
        rm -f hvmloader.tmp
 
-roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin 
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../etherboot/eb-roms.h 
../extboot/extboot.bin
+roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin \
+       ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../etherboot/eb-roms.h \
+       ../extboot/extboot.bin
        sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
        sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
-       sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin 
>> roms.h
+       sh ./mkhex vgabios_cirrusvga \
+               ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
        cat ../etherboot/eb-roms.h >> roms.h
        sh ./mkhex extboot ../extboot/extboot.bin >> roms.h
 
diff -r db943e8d1051 -r 69c951243105 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Tue Apr 01 10:09:33 2008 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c      Tue Apr 01 17:21:05 2008 +0100
@@ -420,6 +420,8 @@ int main(void)
 
     init_hypercalls();
 
+    printf("CPU speed is %u MHz\n", get_cpu_mhz());
+
     printf("Writing SMBIOS tables ...\n");
     smbios_sz = hvm_write_smbios_tables();
 
diff -r db943e8d1051 -r 69c951243105 tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c Tue Apr 01 10:09:33 2008 +0100
+++ b/tools/firmware/hvmloader/smbios.c Tue Apr 01 17:21:05 2008 +0100
@@ -21,6 +21,7 @@
  */
 
 #include <stdint.h>
+#include <xen/xen.h>
 #include <xen/version.h>
 #include "smbios_types.h"
 #include "util.h"
@@ -246,13 +247,14 @@ smbios_entry_point_init(void *start,
     int i;
     struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
 
+    memset(ep, 0, sizeof(*ep));
+
     strncpy(ep->anchor_string, "_SM_", 4);
     ep->length = 0x1f;
     ep->smbios_major_version = 2;
     ep->smbios_minor_version = 4;
     ep->max_structure_size = max_structure_size;
     ep->entry_point_revision = 0;
-    memset(ep->formatted_area, 0, 5);
     strncpy(ep->intermediate_anchor_string, "_DMI_", 5);
     
     ep->structure_table_length = structure_table_length;
@@ -260,9 +262,6 @@ smbios_entry_point_init(void *start,
     ep->number_of_structures = number_of_structures;
     ep->smbios_bcd_revision = 0x24;
 
-    ep->checksum = 0;
-    ep->intermediate_checksum = 0;
-    
     sum = 0;
     for ( i = 0; i < 0x10; i++ )
         sum += ((int8_t *)start)[i];
@@ -280,22 +279,27 @@ smbios_type_0_init(void *start, const ch
                    uint32_t xen_major_version, uint32_t xen_minor_version)
 {
     struct smbios_type_0 *p = (struct smbios_type_0 *)start;
-    
+    static const char *smbios_release_date = __SMBIOS_DATE__;
+
+    memset(p, 0, sizeof(*p));
+
     p->header.type = 0;
     p->header.length = sizeof(struct smbios_type_0);
     p->header.handle = 0;
-    
+
     p->vendor_str = 1;
     p->version_str = 2;
     p->starting_address_segment = 0xe800;
-    p->release_date_str = 0;
+    p->release_date_str = 3;
     p->rom_size = 0;
-    
-    memset(p->characteristics, 0, 8);
-    p->characteristics[7] = 0x08; /* BIOS characteristics not supported */
-    p->characteristics_extension_bytes[0] = 0;
-    p->characteristics_extension_bytes[1] = 0;
-    
+
+    /* BIOS Characteristics. */
+    p->characteristics[0] = 0x80; /* PCI is supported */
+    p->characteristics[2] = 0x08; /* EDD is supported */
+
+    /* Extended Characteristics: Enable Targeted Content Distribution. */
+    p->characteristics_extension_bytes[1] = 0x04;
+
     p->major_release = (uint8_t) xen_major_version;
     p->minor_release = (uint8_t) xen_minor_version;
     p->embedded_controller_major = 0xff;
@@ -306,6 +310,8 @@ smbios_type_0_init(void *start, const ch
     start += strlen("Xen") + 1;
     strcpy((char *)start, xen_version);
     start += strlen(xen_version) + 1;
+    strcpy((char *)start, smbios_release_date);
+    start += strlen(smbios_release_date) + 1;
 
     *((uint8_t *)start) = 0;
     return start + 1;
@@ -318,6 +324,9 @@ smbios_type_1_init(void *start, const ch
 {
     char uuid_str[37];
     struct smbios_type_1 *p = (struct smbios_type_1 *)start;
+
+    memset(p, 0, sizeof(*p));
+
     p->header.type = 1;
     p->header.length = sizeof(struct smbios_type_1);
     p->header.handle = 0x100;
@@ -355,6 +364,8 @@ smbios_type_3_init(void *start)
 {
     struct smbios_type_3 *p = (struct smbios_type_3 *)start;
     
+    memset(p, 0, sizeof(*p));
+
     p->header.type = 3;
     p->header.length = sizeof(struct smbios_type_3);
     p->header.handle = 0x300;
@@ -379,11 +390,14 @@ smbios_type_3_init(void *start)
 
 /* Type 4 -- Processor Information */
 static void *
-smbios_type_4_init(void *start, unsigned int cpu_number, char 
*cpu_manufacturer)
+smbios_type_4_init(
+    void *start, unsigned int cpu_number, char *cpu_manufacturer)
 {
     char buf[80]; 
     struct smbios_type_4 *p = (struct smbios_type_4 *)start;
     uint32_t eax, ebx, ecx, edx;
+
+    memset(p, 0, sizeof(*p));
 
     p->header.type = 4;
     p->header.length = sizeof(struct smbios_type_4);
@@ -403,8 +417,7 @@ smbios_type_4_init(void *start, unsigned
     p->voltage = 0;
     p->external_clock = 0;
 
-    p->max_speed = 0; /* unknown */
-    p->current_speed = 0; /* unknown */
+    p->max_speed = p->current_speed = get_cpu_mhz();
 
     p->status = 0x41; /* socket populated, CPU enabled */
     p->upgrade = 0x01; /* other */
@@ -430,6 +443,8 @@ smbios_type_16_init(void *start, uint32_
 smbios_type_16_init(void *start, uint32_t memsize)
 {
     struct smbios_type_16 *p = (struct smbios_type_16*)start;
+
+    memset(p, 0, sizeof(*p));
 
     p->header.type = 16;
     p->header.handle = 0x1000;
@@ -453,6 +468,8 @@ smbios_type_17_init(void *start, uint32_
 {
     struct smbios_type_17 *p = (struct smbios_type_17 *)start;
     
+    memset(p, 0, sizeof(*p));
+
     p->header.type = 17;
     p->header.length = sizeof(struct smbios_type_17);
     p->header.handle = 0x1100;
@@ -484,6 +501,8 @@ smbios_type_19_init(void *start, uint32_
 {
     struct smbios_type_19 *p = (struct smbios_type_19 *)start;
     
+    memset(p, 0, sizeof(*p));
+
     p->header.type = 19;
     p->header.length = sizeof(struct smbios_type_19);
     p->header.handle = 0x1300;
@@ -503,6 +522,8 @@ smbios_type_20_init(void *start, uint32_
 smbios_type_20_init(void *start, uint32_t memory_size_mb)
 {
     struct smbios_type_20 *p = (struct smbios_type_20 *)start;
+
+    memset(p, 0, sizeof(*p));
 
     p->header.type = 20;
     p->header.length = sizeof(struct smbios_type_20);
@@ -528,6 +549,8 @@ smbios_type_32_init(void *start)
 {
     struct smbios_type_32 *p = (struct smbios_type_32 *)start;
 
+    memset(p, 0, sizeof(*p));
+
     p->header.type = 32;
     p->header.length = sizeof(struct smbios_type_32);
     p->header.handle = 0x2000;
@@ -544,6 +567,8 @@ smbios_type_127_init(void *start)
 smbios_type_127_init(void *start)
 {
     struct smbios_type_127 *p = (struct smbios_type_127 *)start;
+
+    memset(p, 0, sizeof(*p));
 
     p->header.type = 127;
     p->header.length = sizeof(struct smbios_type_127);
diff -r db943e8d1051 -r 69c951243105 tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c   Tue Apr 01 10:09:33 2008 +0100
+++ b/tools/firmware/hvmloader/util.c   Tue Apr 01 17:21:05 2008 +0100
@@ -21,7 +21,10 @@
 #include "util.h"
 #include "config.h"
 #include "e820.h"
+#include "hypercall.h"
 #include <stdint.h>
+#include <xen/xen.h>
+#include <xen/memory.h>
 #include <xen/hvm/hvm_info_table.h>
 
 void outb(uint16_t addr, uint8_t val)
@@ -585,6 +588,56 @@ int get_apic_mode(void)
     return (t ? t->apic_mode : 1);
 }
 
+uint16_t get_cpu_mhz(void)
+{
+    struct xen_add_to_physmap xatp;
+    struct shared_info *shared_info = (struct shared_info *)0xa0000;
+    struct vcpu_time_info *info = &shared_info->vcpu_info[0].time;
+    uint64_t cpu_khz;
+    uint32_t tsc_to_nsec_mul, version;
+    int8_t tsc_shift;
+
+    static uint16_t cpu_mhz;
+    if ( cpu_mhz != 0 )
+        return cpu_mhz;
+
+    /* Map shared-info page to 0xa0000 (i.e., overlap VGA hole). */
+    xatp.domid = DOMID_SELF;
+    xatp.space = XENMAPSPACE_shared_info;
+    xatp.idx   = 0;
+    xatp.gpfn  = (unsigned long)shared_info >> 12;
+    if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
+        BUG();
+
+    /* Get a consistent snapshot of scale factor (multiplier and shift). */
+    do {
+        version = info->version;
+        rmb();
+        tsc_to_nsec_mul = info->tsc_to_system_mul;
+        tsc_shift       = info->tsc_shift;
+        rmb();
+    } while ((version & 1) | (version ^ info->version));
+
+    /* Compute CPU speed in kHz. */
+    cpu_khz = 1000000ull << 32;
+    do_div(cpu_khz, tsc_to_nsec_mul);
+    if ( tsc_shift < 0 )
+        cpu_khz = cpu_khz << -tsc_shift;
+    else
+        cpu_khz = cpu_khz >> tsc_shift;
+
+    /* Get the VGA MMIO hole back by remapping shared info to scratch. */
+    xatp.domid = DOMID_SELF;
+    xatp.space = XENMAPSPACE_shared_info;
+    xatp.idx   = 0;
+    xatp.gpfn  = 0xfffff; /* scratch pfn */
+    if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
+        BUG();
+
+    cpu_mhz = (uint16_t)(((uint32_t)cpu_khz + 500) / 1000);
+    return cpu_mhz;
+}
+
 /*
  * Local variables:
  * mode: C
diff -r db943e8d1051 -r 69c951243105 tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h   Tue Apr 01 10:09:33 2008 +0100
+++ b/tools/firmware/hvmloader/util.h   Tue Apr 01 17:21:05 2008 +0100
@@ -10,11 +10,11 @@
 #undef NULL
 #define NULL ((void*)0)
 
-extern void __assert_failed(char *assertion, char *file, int line)
+void __assert_failed(char *assertion, char *file, int line)
     __attribute__((noreturn));
 #define ASSERT(p) \
     do { if (!(p)) __assert_failed(#p, __FILE__, __LINE__); } while (0)
-extern void __bug(char *file, int line) __attribute__((noreturn));
+void __bug(char *file, int line) __attribute__((noreturn));
 #define BUG() __bug(__FILE__, __LINE__)
 #define BUG_ON(p) do { if (p) BUG(); } while (0)
 #define BUILD_BUG_ON(p) ((void)sizeof(char[1 - 2 * !!(p)]))
@@ -49,9 +49,53 @@ void pci_write(uint32_t devfn, uint32_t 
 #define pci_writew(devfn, reg, val) (pci_write(devfn, reg, 2, (uint16_t)val))
 #define pci_writel(devfn, reg, val) (pci_write(devfn, reg, 4, (uint32_t)val))
 
+/* Get CPU speed in MHz. */
+uint16_t get_cpu_mhz(void);
+
 /* Do cpuid instruction, with operation 'idx' */
 void cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx,
            uint32_t *ecx, uint32_t *edx);
+
+/* Read the TSC register. */
+static inline uint64_t rdtsc(void)
+{
+    uint64_t tsc;
+    asm volatile ( "rdtsc" : "=A" (tsc) );
+    return tsc;
+}
+
+/* Relax the CPU and let the compiler know that time passes. */
+static inline void cpu_relax(void)
+{
+    asm volatile ( "rep ; nop" : : : "memory" );
+}
+
+/* Memory barriers. */
+#define barrier() asm volatile ( "" : : : "memory" )
+#define rmb()     barrier()
+#define wmb()     barrier()
+
+/*
+ * Divide a 64-bit dividend by a 32-bit divisor.
+ * (1) Overwrites the 64-bit dividend _in_place_ with the quotient
+ * (2) Returns the 32-bit remainder
+ */
+#define do_div(n, base) ({                                      \
+    unsigned long __upper, __low, __high, __mod, __base;        \
+    __base = (base);                                            \
+    asm ( "" : "=a" (__low), "=d" (__high) : "A" (n) );         \
+    __upper = __high;                                           \
+    if ( __high )                                               \
+    {                                                           \
+        __upper = __high % (__base);                            \
+        __high = __high / (__base);                             \
+    }                                                           \
+    asm ( "divl %2"                                             \
+          : "=a" (__low), "=d" (__mod)                          \
+          : "rm" (__base), "0" (__low), "1" (__upper) );        \
+    asm ( "" : "=A" (n) : "a" (__low), "d" (__high) );          \
+    __mod;                                                      \
+})
 
 /* HVM-builder info. */
 int get_vcpu_nr(void);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.