WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] hvmloader: Properly implement some more S

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] hvmloader: Properly implement some more SMBIOS fields.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 08 Apr 2008 02:00:08 -0700
Delivery-date: Tue, 08 Apr 2008 02:00:11 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] hvmloader: Properly implement some more SMBIOS fields., Xen patchbot-unstable <=