[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |