]> xenbits.xen.org Git - xenclient/xen-pq.git/commitdiff
SMBIOS OEM types passthrough implementation.
authorKamala Narasimhan <kamala.narasimhan@citrix.com>
Thu, 23 Jul 2009 15:42:45 +0000 (11:42 -0400)
committerKamala Narasimhan <kamala.narasimhan@citrix.com>
Thu, 23 Jul 2009 15:42:45 +0000 (11:42 -0400)
master/acpi-slic
master/oem-features
master/smbios

index bcada23c46026a5a6ee6a77be0e82a7949529679..60f2599e7b68098975dd162b37d00d94a704618c 100644 (file)
@@ -1,7 +1,8 @@
-diff -Nur a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acpi/build.c
---- a/tools/firmware/hvmloader/acpi/build.c    2009-04-01 16:02:46.000000000 -0400
-+++ b/tools/firmware/hvmloader/acpi/build.c    2009-04-01 15:57:01.000000000 -0400
-@@ -59,7 +59,16 @@
+diff --git a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acpi/build.c
+index 97dcdb5..0513b9c 100644
+--- a/tools/firmware/hvmloader/acpi/build.c
++++ b/tools/firmware/hvmloader/acpi/build.c
+@@ -59,7 +59,16 @@ static uint8_t battery_port_exists(void)
      return 1;
  }
  
@@ -19,7 +20,7 @@ diff -Nur a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acp
  {
      struct acpi_20_madt_intsrcovr *intsrcovr;
      struct acpi_20_madt_ioapic    *io_apic;
-@@ -69,7 +78,14 @@
+@@ -69,7 +78,14 @@ static int construct_madt(struct acpi_20_madt *madt)
      memset(madt, 0, sizeof(*madt));
      madt->header.signature    = ACPI_2_0_MADT_SIGNATURE;
      madt->header.revision     = ACPI_2_0_MADT_REVISION;
@@ -35,7 +36,7 @@ diff -Nur a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acp
      fixed_strcpy(madt->header.oem_table_id, ACPI_OEM_TABLE_ID);
      madt->header.oem_revision = ACPI_OEM_REVISION;
      madt->header.creator_id   = ACPI_CREATOR_ID;
-@@ -136,14 +152,21 @@
+@@ -136,14 +152,21 @@ static int construct_madt(struct acpi_20_madt *madt)
      return align16(offset);
  }
  
@@ -59,7 +60,7 @@ diff -Nur a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acp
      fixed_strcpy(hpet->header.oem_table_id, ACPI_OEM_TABLE_ID);
      hpet->header.oem_revision = ACPI_OEM_REVISION;
      hpet->header.creator_id   = ACPI_CREATOR_ID;
-@@ -158,7 +181,7 @@
+@@ -158,7 +181,7 @@ static int construct_hpet(struct acpi_20_hpet *hpet)
      return offset;
  }
  
@@ -68,7 +69,7 @@ diff -Nur a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acp
  {
      int offset = 0, nr_tables = 0;
      struct acpi_20_madt *madt;
-@@ -172,7 +195,7 @@
+@@ -172,7 +195,7 @@ static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
      if ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode )
      {
          madt = (struct acpi_20_madt *)&buf[offset];
@@ -77,7 +78,7 @@ diff -Nur a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acp
          table_ptrs[nr_tables++] = (unsigned long)madt;
      }
  
-@@ -180,7 +203,7 @@
+@@ -180,7 +203,7 @@ static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
      if ( hpet_exists(ACPI_HPET_ADDRESS) )
      {
          hpet = (struct acpi_20_hpet *)&buf[offset];
@@ -86,7 +87,7 @@ diff -Nur a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acp
          table_ptrs[nr_tables++] = (unsigned long)hpet;
      }
  
-@@ -191,6 +214,14 @@
+@@ -191,6 +214,14 @@ static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
          offset += align16(sizeof(AmlCode_PM));
      }
  
@@ -101,7 +102,7 @@ diff -Nur a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acp
      /* TPM TCPA and SSDT. */
      tis_hdr = (uint16_t *)0xFED40F00;
      if ( (tis_hdr[0] == tis_signature[0]) &&
-@@ -209,7 +240,14 @@
+@@ -209,7 +240,14 @@ static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
          tcpa->header.signature = ACPI_2_0_TCPA_SIGNATURE;
          tcpa->header.length    = sizeof(*tcpa);
          tcpa->header.revision  = ACPI_2_0_TCPA_REVISION;
@@ -117,7 +118,7 @@ diff -Nur a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acp
          fixed_strcpy(tcpa->header.oem_table_id, ACPI_OEM_TABLE_ID);
          tcpa->header.oem_revision = ACPI_OEM_REVISION;
          tcpa->header.creator_id   = ACPI_CREATOR_ID;
-@@ -240,6 +278,21 @@
+@@ -240,6 +278,21 @@ static void __acpi_build_tables(uint8_t *buf, int *low_sz, int *high_sz)
      unsigned char       *dsdt;
      unsigned long        secondary_tables[16];
      int                  offset = 0, i;
@@ -139,7 +140,7 @@ diff -Nur a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acp
  
      /*
       * Fill in high-memory data structures, starting at @buf.
-@@ -283,7 +336,7 @@
+@@ -283,7 +336,7 @@ static void __acpi_build_tables(uint8_t *buf, int *low_sz, int *high_sz)
                   offsetof(struct acpi_header, checksum),
                   sizeof(struct acpi_20_fadt));
  
@@ -148,10 +149,11 @@ diff -Nur a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acp
  
      xsdt = (struct acpi_20_xsdt *)&buf[offset];
      memcpy(xsdt, &Xsdt, sizeof(struct acpi_header));
-diff -Nur a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c
---- a/tools/firmware/hvmloader/util.c  2009-04-01 16:02:51.000000000 -0400
-+++ b/tools/firmware/hvmloader/util.c  2009-04-01 15:47:57.000000000 -0400
-@@ -680,6 +680,32 @@
+diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c
+index 2bb7b2b..013fa25 100644
+--- a/tools/firmware/hvmloader/util.c
++++ b/tools/firmware/hvmloader/util.c
+@@ -680,6 +680,32 @@ struct hvm_sminfo_table *get_hvm_sminfo_table(void)
      return table;
  }
  
@@ -171,8 +173,8 @@ diff -Nur a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c
 +        validated = 1;
 +        return table;
 +    }
-+  
-+    if ( validate_hvm_info_table((uint8_t*)t, t->slic_length + sizeof(struct hvm_acinfo_table), t->signature, "AC INFO", 7) )        
++
++    if ( validate_hvm_info_table((uint8_t*)t, t->slic_length + sizeof(struct hvm_acinfo_table), t->signature, "AC INFO", 7) )
 +        table = t;
 +    else
 +        printf("Bad or missing HVM SMBIOS info table\n");
@@ -181,23 +183,25 @@ diff -Nur a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c
 +    return table;
 +}
 +
- struct hvm_smtable_header * get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type)
+ struct hvm_smtable_header * get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type, uint32_t *iter)
  {
-     struct hvm_smtable_header *header = 
-diff -Nur a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h
---- a/tools/firmware/hvmloader/util.h  2009-04-01 16:02:51.000000000 -0400
-+++ b/tools/firmware/hvmloader/util.h  2009-04-01 15:48:13.000000000 -0400
-@@ -113,6 +113,7 @@
+     struct hvm_smoem_types_header *sm_oem_types;
+diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h
+index 9dead96..9191f2a 100644
+--- a/tools/firmware/hvmloader/util.h
++++ b/tools/firmware/hvmloader/util.h
+@@ -113,6 +113,7 @@ struct hvm_info_table *get_hvm_info_table(void);
  
  /* HVM-build SMBIOS/ACPI info extensions */
  struct hvm_sminfo_table *get_hvm_sminfo_table(void);
 +struct hvm_acinfo_table *get_hvm_acinfo_table(void);
- struct hvm_smtable_header * get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type);
- /* String and memory functions */
-diff -Nur a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
---- a/tools/libxc/xc_dom_x86.c 2009-04-01 14:06:29.000000000 -0400
-+++ b/tools/libxc/xc_dom_x86.c 2009-04-01 16:00:48.000000000 -0400
+ struct hvm_smtable_header * get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type, uint32_t *iter);
+ struct hvm_smoem_types * get_smoem_types_ptr();
+ struct hvm_smtable_header * get_next_sminfo_by_type(struct hvm_smtable_header *header, uint8_t type, uint32_t *iter); 
+diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
+index 6ae9487..90a1e5f 100644
+--- a/tools/libxc/xc_dom_x86.c
++++ b/tools/libxc/xc_dom_x86.c
 @@ -17,7 +17,6 @@
  #include <xen/xen.h>
  #include <xen/foreign/x86_32.h>
@@ -206,9 +210,10 @@ diff -Nur a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
  #include <xen/io/protocols.h>
  
  #include "xg_private.h"
-diff -Nur a/xen/include/public/hvm/hvm_info_table.h b/xen/include/public/hvm/hvm_info_table.h
---- a/xen/include/public/hvm/hvm_info_table.h  2009-04-01 16:02:51.000000000 -0400
-+++ b/xen/include/public/hvm/hvm_info_table.h  2009-04-01 15:41:59.000000000 -0400
+diff --git a/xen/include/public/hvm/hvm_info_table.h b/xen/include/public/hvm/hvm_info_table.h
+index 3388479..ee417b3 100644
+--- a/xen/include/public/hvm/hvm_info_table.h
++++ b/xen/include/public/hvm/hvm_info_table.h
 @@ -32,8 +32,12 @@
  #define HVM_SMINFO_OFFSET    0x0
  #define HVM_SMINFO_PADDR     ((HVM_INFO_PFN << 12) + HVM_SMINFO_OFFSET)
@@ -222,7 +227,7 @@ diff -Nur a/xen/include/public/hvm/hvm_info_table.h b/xen/include/public/hvm/hvm
  
  struct hvm_info_table {
      char        signature[8]; /* "HVM INFO" */
-@@ -83,4 +87,19 @@
+@@ -87,4 +91,19 @@ struct hvm_smtable_header {
      uint32_t    sm_length; /* beginning after this stucture, includes fixed table, string list, and terminator */
  };
  
index 06cc5aa74680205b9b949bf30c11b7a19e3c82a8..9fd0aaf9426859bec61d5e8e7842eaec70709f37 100644 (file)
@@ -40,7 +40,7 @@ index f9f6bc3..6ef2af8 100644
        $(MAKE) iasl
        iasl -tc $<
 diff --git a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acpi/build.c
-index 0513b9c..02ce969 100644
+index 0513b9c..93caa15 100644
 --- a/tools/firmware/hvmloader/acpi/build.c
 +++ b/tools/firmware/hvmloader/acpi/build.c
 @@ -19,8 +19,12 @@
@@ -101,7 +101,7 @@ index 0513b9c..02ce969 100644
 +    if ( pa_sm == NULL )
 +        return 0;
 +
-+    header = (struct hvm_smtable_header *)get_sminfo_by_type(pa_sm, 1);
++    header = (struct hvm_smtable_header *)get_sminfo_by_type(pa_sm, 1, NULL);
 +    if ( header == NULL )
 +        return 0;
 +    if ( header->sm_length < sizeof(struct smbios_type_1) )
index 972f8f61855e471bc60f5562f285a262fbb851a4..678a07e84fd952b5463af06f53fd1e090a243979 100644 (file)
@@ -1,6 +1,9 @@
 diff
+diff --git a/oem/dell-960-optiplex-smbios.patch b/oem/dell-960-optiplex-smbios.patch
+new file mode 100644
+index 0000000..bd5613e
 --- /dev/null
-+++ b/oem/dell-960-optiplex-smbios.patch       2009-04-01 14:15:16.000000000 -0400
++++ b/oem/dell-960-optiplex-smbios.patch
 @@ -0,0 +1,49 @@
 +diff -Nur a/tools/firmware/hvmloader/markers.h b/tools/firmware/hvmloader/markers.h
 +--- a/tools/firmware/hvmloader/markers.h      2008-11-25 12:47:54.000000000 -0500
@@ -51,9 +54,11 @@ diff
 + };
 + 
 + #endif /* __HVMLOADER_MARKERS_H__ */
-diff
---- /dev/null 
-+++ b/oem/dell-e6500-latitude-smbios.patch     2009-04-01 14:15:16.000000000 -0400
+diff --git a/oem/dell-e6500-latitude-smbios.patch b/oem/dell-e6500-latitude-smbios.patch
+new file mode 100644
+index 0000000..b949c7c
+--- /dev/null
++++ b/oem/dell-e6500-latitude-smbios.patch
 @@ -0,0 +1,49 @@
 +diff -Nur a/tools/firmware/hvmloader/markers.h b/tools/firmware/hvmloader/markers.h
 +--- a/tools/firmware/hvmloader/markers.h      2008-12-15 14:44:08.000000000 -0500
@@ -104,9 +109,11 @@ diff
 + };
 + 
 + #endif /* __HVMLOADER_MARKERS_H__ */
-diff 
---- /dev/null 
-+++ b/oem/hp-6930p-elitebook-smbios.patch      2009-04-01 14:15:16.000000000 -0400
+diff --git a/oem/hp-6930p-elitebook-smbios.patch b/oem/hp-6930p-elitebook-smbios.patch
+new file mode 100644
+index 0000000..8441b2a
+--- /dev/null
++++ b/oem/hp-6930p-elitebook-smbios.patch
 @@ -0,0 +1,67 @@
 +diff -Nur a/tools/firmware/hvmloader/markers.h b/tools/firmware/hvmloader/markers.h
 +--- a/tools/firmware/hvmloader/markers.h      2008-11-25 12:47:54.000000000 -0500
@@ -175,9 +182,11 @@ diff
 + };
 + 
 + #endif /* __HVMLOADER_MARKERS_H__ */
-diff 
---- /dev/null 
-+++ b/oem/lenovo-x200-thinkpad-smbios.patch    2009-04-01 14:15:16.000000000 -0400
+diff --git a/oem/lenovo-x200-thinkpad-smbios.patch b/oem/lenovo-x200-thinkpad-smbios.patch
+new file mode 100644
+index 0000000..26d1f09
+--- /dev/null
++++ b/oem/lenovo-x200-thinkpad-smbios.patch
 @@ -0,0 +1,61 @@
 +diff -Nur a/tools/firmware/hvmloader/markers.h b/tools/firmware/hvmloader/markers.h
 +--- a/tools/firmware/hvmloader/markers.h      2008-12-15 14:44:08.000000000 -0500
@@ -240,9 +249,11 @@ diff
 + };
 + 
 + #endif /* __HVMLOADER_MARKERS_H__ */
-diff
---- /dev/null 
-+++ b/tools/firmware/hvmloader/markers.h       2009-04-01 14:15:17.000000000 -0400
+diff --git a/tools/firmware/hvmloader/markers.h b/tools/firmware/hvmloader/markers.h
+new file mode 100644
+index 0000000..7673d22
+--- /dev/null
++++ b/tools/firmware/hvmloader/markers.h
 @@ -0,0 +1,71 @@
 +#ifndef __HVMLOADER_MARKERS_H__
 +#define __HVMLOADER_MARKERS_H__
@@ -315,9 +326,10 @@ diff
 +};
 +
 +#endif /* __HVMLOADER_MARKERS_H__ */
-diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.c
---- a/tools/firmware/hvmloader/smbios.c        2009-04-01 14:06:28.000000000 -0400
-+++ b/tools/firmware/hvmloader/smbios.c        2009-04-01 15:34:18.000000000 -0400
+diff --git a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.c
+index 64fa799..a58dac4 100644
+--- a/tools/firmware/hvmloader/smbios.c
++++ b/tools/firmware/hvmloader/smbios.c
 @@ -27,6 +27,7 @@
  #include "util.h"
  #include "hypercall.h"
@@ -326,7 +338,7 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
  
  static int
  write_smbios_tables(void *start,
-@@ -54,6 +55,8 @@
+@@ -54,6 +55,8 @@ static void *
  smbios_type_4_init(void *start, unsigned int cpu_number,
                     char *cpu_manufacturer);
  static void *
@@ -335,7 +347,27 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
  smbios_type_16_init(void *start, uint32_t memory_size_mb, int nr_mem_devs);
  static void *
  smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance);
-@@ -112,6 +115,7 @@
+@@ -65,6 +68,8 @@ static void *
+ smbios_type_32_init(void *start);
+ static void *
+ smbios_type_127_init(void *start);
++static void *
++smbios_type_oem_init(void *start, struct hvm_smtable_header *header, uint8_t type, uint8_t instance);
+ static void
+ get_cpu_manufacturer(char *buf, int len)
+@@ -93,6 +98,10 @@ write_smbios_tables(void *start,
+     char *p, *q;
+     char cpu_manufacturer[15];
+     int i, nr_mem_devs;
++    uint32_t iter = 0;
++    uint8_t num_oem_types, count, *oem_types, instance = 0;
++    struct hvm_smoem_types_header *oem_types_header;
++    struct hvm_smtable_header *header = NULL;
+     get_cpu_manufacturer(cpu_manufacturer, 15);
+@@ -112,6 +121,7 @@ write_smbios_tables(void *start,
      do_struct(smbios_type_3_init(p));
      for ( cpu_num = 1; cpu_num <= vcpus; cpu_num++ )
          do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer));
@@ -343,16 +375,32 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
  
      /* Each 'memory device' covers up to 16GB of address space. */
      nr_mem_devs = (memsize + 0x3fff) >> 14;
-@@ -127,6 +131,8 @@
+@@ -127,6 +137,24 @@ write_smbios_tables(void *start,
      }
  
      do_struct(smbios_type_32_init(p));
-+    /* NOTE: future enhancement - vendor specific structures (range 128 - 256) would be 
-+       processed and added here */
++
++    oem_types_header = get_smoem_types_ptr();
++    if ( oem_types_header != NULL && oem_types_header->sm_oem_types_length > 0 ) 
++    {
++        num_oem_types = oem_types_header->sm_oem_types_length / sizeof(uint8_t);
++        oem_types = (uint8_t *)oem_types_header + sizeof(struct hvm_smoem_types_header);
++        for ( count = 0; count < num_oem_types; count++ )
++        {
++            while ( (header = get_next_sminfo_by_type(header, oem_types[count], &iter)) != NULL ) 
++            {
++                do_struct(smbios_type_oem_init(p, header, oem_types[count], instance));
++                instance++;
++            }
++            header = NULL;
++            iter = instance = 0;
++        }
++    } 
++
      do_struct(smbios_type_127_init(p));
  
  #undef do_struct
-@@ -280,9 +286,33 @@
+@@ -280,9 +308,33 @@ static void *
  smbios_type_0_init(void *start, const char *xen_version,
                     uint32_t xen_major_version, uint32_t xen_minor_version)
  {
@@ -365,7 +413,7 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
 +    /* if passed a struct, use it */
 +    pa_sm = get_hvm_sminfo_table();
 +    while (pa_sm != NULL) {
-+        header = get_sminfo_by_type(pa_sm, 0);
++        header = get_sminfo_by_type(pa_sm, 0, NULL);
 +        if (header == NULL)
 +            break;
 +        if (header->sm_length < sizeof(struct smbios_type_0))
@@ -379,15 +427,15 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
 +        p->characteristics[0] = 0x80; /* PCI is supported */
 +        p->characteristics[2] = 0x08; /* EDD is supported */
 +        p->characteristics_extension_bytes[1] = 0x04; /* Enable Targeted Content Distribution. */
++
 +        return (start + header->sm_length);
 +    }
-+
 +    /* fall back to building our own */
      memset(p, 0, sizeof(*p));
  
      p->header.type = 0;
-@@ -295,6 +325,7 @@
+@@ -295,6 +347,7 @@ smbios_type_0_init(void *start, const char *xen_version,
      p->release_date_str = 3;
      p->rom_size = 0;
  
@@ -395,7 +443,7 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
      /* BIOS Characteristics. */
      p->characteristics[0] = 0x80; /* PCI is supported */
      p->characteristics[2] = 0x08; /* EDD is supported */
-@@ -308,10 +339,16 @@
+@@ -308,10 +361,16 @@ smbios_type_0_init(void *start, const char *xen_version,
      p->embedded_controller_minor = 0xff;
  
      start += sizeof(struct smbios_type_0);
@@ -416,7 +464,7 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
      strcpy((char *)start, smbios_release_date);
      start += strlen(smbios_release_date) + 1;
  
-@@ -326,7 +363,27 @@
+@@ -326,7 +385,27 @@ smbios_type_1_init(void *start, const char *xen_version,
  {
      char uuid_str[37];
      struct smbios_type_1 *p = (struct smbios_type_1 *)start;
@@ -427,7 +475,7 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
 +    /* if passed a struct, use it */
 +    pa_sm = get_hvm_sminfo_table();
 +    while (pa_sm != NULL) {
-+        header = get_sminfo_by_type(pa_sm, 1);
++        header = get_sminfo_by_type(pa_sm, 1, NULL);
 +        if (header == NULL)
 +            break;
 +        if (header->sm_length < sizeof(struct smbios_type_1))
@@ -444,7 +492,7 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
      memset(p, 0, sizeof(*p));
  
      p->header.type = 1;
-@@ -341,20 +398,46 @@
+@@ -341,20 +420,46 @@ smbios_type_1_init(void *start, const char *xen_version,
      memcpy(p->uuid, uuid, 16);
  
      p->wake_up_type = 0x06; /* power switch */
@@ -461,14 +509,6 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
 +    if ( strlen(sys_product_version.value) == 0 ) {
 +        strncpy(sys_product_version.value, xen_version, sizeof(sys_product_version.value));
 +    }
-+    
-+    strcpy((char *)start, sys_product_version.value);
-+    start += strlen(sys_product_version.value) + 1;
-+
-+    if ( strlen(sys_product_serial.value) == 0 ) {
-+        uuid_to_string(uuid_str, uuid); 
-+        strncpy(sys_product_serial.value, uuid_str, sizeof(sys_product_serial.value));
-+    }
      
 -    strcpy((char *)start, "Xen");
 -    start += strlen("Xen") + 1;
@@ -479,6 +519,14 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
 -    uuid_to_string(uuid_str, uuid); 
 -    strcpy((char *)start, uuid_str);
 -    start += strlen(uuid_str) + 1;
++    strcpy((char *)start, sys_product_version.value);
++    start += strlen(sys_product_version.value) + 1;
++
++    if ( strlen(sys_product_serial.value) == 0 ) {
++        uuid_to_string(uuid_str, uuid); 
++        strncpy(sys_product_serial.value, uuid_str, sizeof(sys_product_serial.value));
++    }
++    
 +    strcpy((char *)start, sys_product_serial.value);
 +    start += strlen(sys_product_serial.value) + 1;
 +
@@ -502,7 +550,7 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
      *((uint8_t *)start) = 0;
      
      return start+1; 
-@@ -365,7 +448,26 @@
+@@ -365,7 +470,26 @@ static void *
  smbios_type_3_init(void *start)
  {
      struct smbios_type_3 *p = (struct smbios_type_3 *)start;
@@ -513,7 +561,7 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
 +    /* if passed a struct, use it */
 +    pa_sm = get_hvm_sminfo_table();
 +    while (pa_sm != NULL) {
-+        header = get_sminfo_by_type(pa_sm, 3);
++        header = get_sminfo_by_type(pa_sm, 3, NULL);
 +        if (header == NULL)
 +            break;
 +        if (header->sm_length < sizeof(struct smbios_type_3))
@@ -530,7 +578,7 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
      memset(p, 0, sizeof(*p));
  
      p->header.type = 3;
-@@ -384,8 +486,18 @@
+@@ -384,8 +508,18 @@ smbios_type_3_init(void *start)
  
      start += sizeof(struct smbios_type_3);
      
@@ -551,7 +599,7 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
      *((uint8_t *)start) = 0;
      return start+1;
  }
-@@ -440,6 +552,52 @@
+@@ -440,6 +574,52 @@ smbios_type_4_init(
      return start+1;
  }
  
@@ -567,7 +615,7 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
 +    /* if passed a struct, use it */
 +    pa_sm = get_hvm_sminfo_table();
 +    while (pa_sm != NULL) {
-+        header = get_sminfo_by_type(pa_sm, 11);
++        header = get_sminfo_by_type(pa_sm, 11, NULL);
 +        if (header == NULL)
 +            break;
 +        if (header->sm_length < sizeof(struct smbios_type_11))
@@ -604,10 +652,29 @@ diff -Nur a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.
  /* Type 16 -- Physical Memory Array */
  static void *
  smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs)
-diff -Nur a/tools/firmware/hvmloader/smbios_types.h b/tools/firmware/hvmloader/smbios_types.h
---- a/tools/firmware/hvmloader/smbios_types.h  2009-04-01 14:06:28.000000000 -0400
-+++ b/tools/firmware/hvmloader/smbios_types.h  2009-04-01 15:28:52.000000000 -0400
-@@ -115,6 +115,12 @@
+@@ -584,6 +764,17 @@ smbios_type_127_init(void *start)
+     return start + 2;
+ }
++/* OEM Types */
++static void *
++smbios_type_oem_init(void *start, struct hvm_smtable_header *header, uint8_t type, uint8_t instance)
++{
++    struct smbios_structure_header * sm_struct_header = 
++        (struct smbios_structure_header *)((uint8_t*)header + sizeof(struct hvm_smtable_header));
++    sm_struct_header->handle = (type << 8) + instance; 
++    memcpy(start, (uint8_t*)sm_struct_header, header->sm_length);
++    return (start + header->sm_length);
++}
++
+ /*
+  * Local variables:
+  * mode: C
+diff --git a/tools/firmware/hvmloader/smbios_types.h b/tools/firmware/hvmloader/smbios_types.h
+index 273db4a..e57464e 100644
+--- a/tools/firmware/hvmloader/smbios_types.h
++++ b/tools/firmware/hvmloader/smbios_types.h
+@@ -115,6 +115,12 @@ struct smbios_type_4 {
        uint8_t upgrade;
  } __attribute__ ((packed));
  
@@ -620,10 +687,11 @@ diff -Nur a/tools/firmware/hvmloader/smbios_types.h b/tools/firmware/hvmloader/s
  /* SMBIOS type 16 - Physical Memory Array
   *   Associated with one type 17 (Memory Device).
   */
-diff -Nur a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c
---- a/tools/firmware/hvmloader/util.c  2009-04-01 14:06:28.000000000 -0400
-+++ b/tools/firmware/hvmloader/util.c  2009-04-01 14:50:01.000000000 -0400
-@@ -542,32 +542,32 @@
+diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c
+index ccf9bf9..530897c 100644
+--- a/tools/firmware/hvmloader/util.c
++++ b/tools/firmware/hvmloader/util.c
+@@ -542,32 +542,32 @@ void __bug(char *file, int line)
          asm volatile ( "ud2" );
  }
  
@@ -672,7 +740,7 @@ diff -Nur a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c
  }
  
  struct hvm_info_table *get_hvm_info_table(void)
-@@ -580,7 +580,11 @@
+@@ -580,7 +580,11 @@ struct hvm_info_table *get_hvm_info_table(void)
  
      t = (struct hvm_info_table *)HVM_INFO_PADDR;
  
@@ -685,7 +753,7 @@ diff -Nur a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c
  
      table = t;
  
-@@ -650,6 +654,52 @@
+@@ -650,6 +654,107 @@ int hpet_exists(unsigned long hpet_base)
      return ((hpet_id >> 16) == 0x8086);
  }
  
@@ -715,46 +783,105 @@ diff -Nur a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c
 +    return table;
 +}
 +
-+struct hvm_smtable_header * get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type)
++struct hvm_smtable_header * get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type, uint32_t *iter)
 +{
-+    struct hvm_smtable_header *header = 
-+        (struct hvm_smtable_header*)((uint8_t*)pa_sm + sizeof(struct hvm_sminfo_table));
++    struct hvm_smoem_types_header *sm_oem_types;
++    struct hvm_smtable_header *header;
 +    uint32_t count;
 +    uint8_t *ptr;
 +
++    if ( iter != NULL )
++        *iter = 0;
++
++    sm_oem_types = (struct hvm_smoem_types_header*)((uint8_t*)pa_sm + sizeof(struct hvm_sminfo_table));
++    header = (struct hvm_smtable_header*)((uint8_t*)sm_oem_types + sizeof(struct hvm_smoem_types_header)
++                                         + sm_oem_types->sm_oem_types_length );
++
 +    for (count = 0; count < pa_sm->sm_count; count++) {
 +        if (header->sm_length == 0) {
 +            printf("Invalid SMINFO tables passed to HVM loader.");
 +            return NULL;
 +        }
 +        ptr = ((uint8_t*)header + sizeof(struct hvm_smtable_header));
-+        if (ptr[0] == type)
++        if (ptr[0] == type) {
++            if ( iter != NULL )
++                *iter = count;
 +            return header;
++        }
 +        header = (struct hvm_smtable_header*)(ptr + header->sm_length);
 +    }
 +    return NULL;
 +}
++
++struct hvm_smtable_header * get_next_sminfo_by_type(struct hvm_smtable_header *header, uint8_t type, uint32_t *iter)
++{
++    uint8_t *ptr;
++    uint32_t count;
++    struct hvm_sminfo_table *pa_sm = get_hvm_sminfo_table();
++
++    if ( pa_sm == NULL || iter == NULL )
++        return NULL;
++
++    if ( header == NULL ) 
++    {
++        header = get_sminfo_by_type(pa_sm, type, iter);
++        return header;
++    }
++
++    header = (struct hvm_smtable_header *)((uint8_t*)header + sizeof(struct hvm_smtable_header) + header->sm_length);
++    for (count = *iter+1; count < pa_sm->sm_count; count++) 
++    {
++        if ( header->sm_length == 0) 
++        {
++            *iter = 0;
++             return NULL;
++        }
++        ptr = ((uint8_t*)header + sizeof(struct hvm_smtable_header));
++        if ( ptr[0] == type) 
++        {
++            *iter = count;
++            return header;
++        }
++        header = (struct hvm_smtable_header*)(ptr + header->sm_length);
++    }
++
++    *iter = 0;
++    return NULL; 
++}
++
++struct hvm_smoem_types_header * get_smoem_types_ptr(void)
++{
++    struct hvm_sminfo_table *pa_sm = get_hvm_sminfo_table();
++    if ( pa_sm == NULL )
++        return NULL;
++
++    return (struct hvm_smoem_types_header*)((uint8_t*)pa_sm + sizeof(struct hvm_sminfo_table));
++}
 +
  /*
   * Local variables:
   * mode: C
-diff -Nur a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h
---- a/tools/firmware/hvmloader/util.h  2009-04-01 14:06:28.000000000 -0400
-+++ b/tools/firmware/hvmloader/util.h  2009-04-01 14:50:19.000000000 -0400
-@@ -111,6 +111,10 @@
+diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h
+index e9e0dfd..9eac225 100644
+--- a/tools/firmware/hvmloader/util.h
++++ b/tools/firmware/hvmloader/util.h
+@@ -111,6 +111,12 @@ static inline void cpu_relax(void)
  struct hvm_info_table *get_hvm_info_table(void);
  #define hvm_info (get_hvm_info_table())
  
 +/* HVM-build SMBIOS/ACPI info extensions */
 +struct hvm_sminfo_table *get_hvm_sminfo_table(void);
-+struct hvm_smtable_header * get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type);
++struct hvm_smtable_header * get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type, uint32_t *iter);
++struct hvm_smoem_types_header * get_smoem_types_ptr(void);
++struct hvm_smtable_header * get_next_sminfo_by_type(struct hvm_smtable_header *header, uint8_t type, uint32_t *iter); 
 +
  /* String and memory functions */
  int strcmp(const char *cs, const char *ct);
  int strncmp(const char *s1, const char *s2, uint32_t n);
-diff -Nur a/xen/include/public/hvm/hvm_info_table.h b/xen/include/public/hvm/hvm_info_table.h
---- a/xen/include/public/hvm/hvm_info_table.h  2009-04-01 14:06:32.000000000 -0400
-+++ b/xen/include/public/hvm/hvm_info_table.h  2009-04-01 14:24:54.000000000 -0400
+diff --git a/xen/include/public/hvm/hvm_info_table.h b/xen/include/public/hvm/hvm_info_table.h
+index b898455..3388479 100644
+--- a/xen/include/public/hvm/hvm_info_table.h
++++ b/xen/include/public/hvm/hvm_info_table.h
 @@ -28,6 +28,12 @@
  #define HVM_INFO_PFN         0x09F
  #define HVM_INFO_OFFSET      0x800
@@ -768,7 +895,7 @@ diff -Nur a/xen/include/public/hvm/hvm_info_table.h b/xen/include/public/hvm/hvm
  
  struct hvm_info_table {
      char        signature[8]; /* "HVM INFO" */
-@@ -66,4 +72,15 @@
+@@ -66,4 +72,19 @@ struct hvm_info_table {
      uint32_t    high_mem_pgend;
  };
  
@@ -779,6 +906,10 @@ diff -Nur a/xen/include/public/hvm/hvm_info_table.h b/xen/include/public/hvm/hvm
 +    uint32_t    sm_count;
 +};
 +
++struct hvm_smoem_types_header {
++   uint32_t sm_oem_types_length; /* Followed by oem type numbers to pass through */
++};
++
 +struct hvm_smtable_header {
 +    uint32_t    sm_length; /* beginning after this stucture, includes fixed table, string list, and terminator */
 +};