]> xenbits.xensource.com Git - xenclient/xen.git/commitdiff
Check for OEM name and model before loading oem specific ssdt.
authorKamala Narasimhan <kamala.narasimhan@citrix.com>
Wed, 4 Mar 2009 19:37:59 +0000 (14:37 -0500)
committerKamala Narasimhan <kamala.narasimhan@citrix.com>
Wed, 4 Mar 2009 19:37:59 +0000 (14:37 -0500)
Now that we support oem value add for more than one OEM, we need this check.

tools/firmware/hvmloader/acpi/build.c
tools/firmware/hvmloader/smbios.c
tools/firmware/hvmloader/util.c
tools/firmware/hvmloader/util.h

index 763c5b0122c7e18be80402d0a3c445e9787ef302..2d35b00fbc2364ee9d981cc60863e057909a30d5 100644 (file)
 #include "ssdt_tpm.h"
 #include "ssdt_pm.h"
 #include "ssdt_hp_6930p_elitebook.h"
+#include "ssdt_dell_latitude_eseries.h"
 #include "../config.h"
 #include "../util.h"
+#include "../smbios_types.h"
 #include <xen/hvm/hvm_info_table.h>
 
 #define align16(sz)        (((sz) + 15) & ~15)
@@ -35,6 +37,12 @@ extern struct acpi_20_facs Facs;
 extern unsigned char AmlCode[];
 extern int DsdtLen;
 
+#define OEM_NAME_DELL                    "Dell"
+#define OEM_NAME_HP                      "Hewlett-Packard"
+#define OEM_MODEL_DELL_LATITUDE_1        "Latitude E4200"
+#define OEM_MODEL_DELL_LATITUDE_2        "Latitude E6500"
+#define OEM_MODEL_HP_EliteBook           "HP EliteBook 6930p"
+
 static void set_checksum(
     void *table, uint32_t checksum_offset, uint32_t length)
 {
@@ -115,6 +123,49 @@ static void pt_update_acpi_tables(struct acpi_header *header, struct hvm_acinfo_
     header->creator_revision = va_ac->creator_revision;
 }
 
+static int construct_oem_ssdt(uint8_t *buf)
+{
+    struct smbios_type_1 *type1_info;
+    char *manufacturer, *model;
+    struct hvm_sminfo_table *pa_sm;
+    struct hvm_smtable_header *header;
+
+    pa_sm = get_hvm_sminfo_table();
+    if ( pa_sm == NULL ) 
+        return 0;
+
+    header = (struct hvm_smtable_header *)get_sminfo_by_type(pa_sm, 1);
+    if ( header == NULL )
+        return 0;
+    if ( header->sm_length < sizeof(struct smbios_type_1) )
+        return 0;
+
+    type1_info = (struct smbios_type_1 *)((char *)header + sizeof(struct hvm_smtable_header));
+    manufacturer = (char *)type1_info + type1_info->header.length;
+    model = manufacturer + strlen(manufacturer) + 1;
+
+    if ( strncmp(manufacturer, OEM_NAME_DELL, strlen(OEM_NAME_DELL)) == 0 )
+    {
+        if ( (strncmp(model, OEM_MODEL_DELL_LATITUDE_1, strlen(OEM_MODEL_DELL_LATITUDE_1)) != 0) && 
+             (strncmp(model, OEM_MODEL_DELL_LATITUDE_2, strlen(OEM_MODEL_DELL_LATITUDE_2)) != 0) )
+            return 0;
+
+       memcpy(buf, AmlCode_DELL_LATITUDE_ESERIES, sizeof(AmlCode_DELL_LATITUDE_ESERIES));
+       return align16(sizeof(AmlCode_DELL_LATITUDE_ESERIES));
+    }
+
+    if ( strncmp(manufacturer, OEM_NAME_HP, strlen(OEM_NAME_HP)) == 0 ) 
+    {
+        if ( strncmp(model, OEM_MODEL_HP_EliteBook, strlen(OEM_MODEL_HP_EliteBook)) != 0 )
+            return 0;
+
+        memcpy(buf, AmlCode_HP_6930P_ELITEBOOK, sizeof(AmlCode_HP_6930P_ELITEBOOK));
+        return align16(sizeof(AmlCode_HP_6930P_ELITEBOOK));
+    }
+    return 0;
+}
+
 static int construct_madt(struct acpi_20_madt *madt, struct hvm_acinfo_table *va_ac)
 {
     struct acpi_20_madt_intsrcovr *intsrcovr;
@@ -230,12 +281,13 @@ static int construct_hpet(struct acpi_20_hpet *hpet, struct hvm_acinfo_table *va
 
 static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs, struct hvm_acinfo_table *va_ac)
 {
-    int offset = 0, nr_tables = 0;
+    int offset = 0, nr_tables = 0, oem_ssdt_offset = 0;
     struct acpi_20_madt *madt;
     struct acpi_20_hpet *hpet;
     struct acpi_20_tcpa *tcpa;
     static const uint16_t tis_signature[] = {0x0001, 0x0001, 0x0001};
     uint16_t *tis_hdr;
+    uint8_t *oem_ssdt;
 
     /* MADT. */
     if ( (get_vcpu_nr() > 1) || get_apic_mode() )
@@ -268,16 +320,15 @@ static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs, s
         offset += align16(va_ac->slic_length);
     }
 
-    /* NOTE:  Once we test and confirm oem value add functionality
-     * on more OEMs, the below logic should be extended to get
-     * OEM type information from SMBIOS and load appropriate SSDT.
-     */
     if ( oem_value_add_exists() )
     {
-        table_ptrs[nr_tables++] = (unsigned long)&buf[offset];
-        memcpy(&buf[offset], AmlCode_HP_6930P_ELITEBOOK,
-            sizeof(AmlCode_HP_6930P_ELITEBOOK));
-        offset += align16(sizeof(AmlCode_HP_6930P_ELITEBOOK));
+        oem_ssdt = &buf[offset];
+        oem_ssdt_offset = construct_oem_ssdt(oem_ssdt); 
+        if ( oem_ssdt_offset != 0 )
+        {
+            offset += oem_ssdt_offset;
+            table_ptrs[nr_tables++] = (unsigned long)oem_ssdt;
+        }
     }
 
     /* TPM TCPA and SSDT. */
index e50d80b20e155be999b5d84e9b40f298dd6f64ae..2761c2f278a353ebb7603a3e724612005c8a91c1 100644 (file)
@@ -36,8 +36,6 @@ write_smbios_tables(void *start,
                     uint8_t uuid[16], char *xen_version,
                     uint32_t xen_major_version, uint32_t xen_minor_version);
 
-static struct hvm_smtable_header *
-get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type);
 static void
 get_cpu_manufacturer(char *buf, int len);
 static void
@@ -72,26 +70,6 @@ smbios_type_32_init(void *start);
 static void *
 smbios_type_127_init(void *start);
 
-static struct hvm_smtable_header *
-get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type)
-{
-    struct hvm_smtable_header *header = (struct hvm_smtable_header*)((uint8_t*)pa_sm + sizeof(struct hvm_sminfo_table));
-    uint32_t count;
-    uint8_t *ptr;
-
-    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)
-            return header;
-        header = (struct hvm_smtable_header*)(ptr + header->sm_length);
-    }
-    return NULL;
-}
-
 static void
 get_cpu_manufacturer(char *buf, int len)
 {
index 99a8e02277e57f736cb4a1b746c13843682d5046..728966c20c7421999186fa5d12e0edfb2923e5f9 100644 (file)
@@ -701,6 +701,26 @@ struct hvm_acinfo_table *get_hvm_acinfo_table(void)
     return table;
 }
 
+struct hvm_smtable_header * get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type)
+{
+    struct hvm_smtable_header *header = 
+        (struct hvm_smtable_header*)((uint8_t*)pa_sm + sizeof(struct hvm_sminfo_table));
+    uint32_t count;
+    uint8_t *ptr;
+
+    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)
+            return header;
+        header = (struct hvm_smtable_header*)(ptr + header->sm_length);
+    }
+    return NULL;
+}
+
 /*
  * Local variables:
  * mode: C
index 4900150e3a66bd66c291683ef827ac2ee2683669..edc28690b1ff4fc446ca26fc34f8094ed9448fb5 100644 (file)
@@ -146,6 +146,7 @@ void cacheattr_init(void);
 void create_mp_tables(void);
 int hvm_write_smbios_tables(void);
 void smp_initialise(void);
+struct hvm_smtable_header * get_sminfo_by_type(struct hvm_sminfo_table *pa_sm, uint8_t type);
 
 #ifndef NDEBUG
 void perform_tests(void);