-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;
}
{
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;
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);
}
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;
}
{
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];
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];
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));
}
/* 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;
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;
/*
* 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));
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;
}
+ 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");
+ 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>
#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)
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 */
};
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
+ };
+
+ #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
+ };
+
+ #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
+ };
+
+ #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
+ };
+
+ #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__
+};
+
+#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"
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 *
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));
/* 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)
{
+ /* 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))
+ 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;
/* 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);
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;
+ /* 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))
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 */
+ 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;
- 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;
+
*((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;
+ /* 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))
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);
*((uint8_t *)start) = 0;
return start+1;
}
-@@ -440,6 +552,52 @@
+@@ -440,6 +574,52 @@ smbios_type_4_init(
return start+1;
}
+ /* 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))
/* 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));
/* 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" );
}
}
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;
table = t;
-@@ -650,6 +654,52 @@
+@@ -650,6 +654,107 @@ int hpet_exists(unsigned long hpet_base)
return ((hpet_id >> 16) == 0x8086);
}
+ 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
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;
};
+ 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 */
+};