From eaeaeb808d18debee88cd2d2b60a51e8c4f416a1 Mon Sep 17 00:00:00 2001 From: Kamala Narasimhan Date: Wed, 4 Mar 2009 14:37:59 -0500 Subject: [PATCH] Check for OEM name and model before loading oem specific ssdt. Now that we support oem value add for more than one OEM, we need this check. --- tools/firmware/hvmloader/acpi/build.c | 69 +++++++++++++++++++++++---- tools/firmware/hvmloader/smbios.c | 22 --------- tools/firmware/hvmloader/util.c | 20 ++++++++ tools/firmware/hvmloader/util.h | 1 + 4 files changed, 81 insertions(+), 31 deletions(-) diff --git a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acpi/build.c index 763c5b0..2d35b00 100644 --- a/tools/firmware/hvmloader/acpi/build.c +++ b/tools/firmware/hvmloader/acpi/build.c @@ -20,8 +20,10 @@ #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 #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. */ diff --git a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.c index e50d80b..2761c2f 100644 --- a/tools/firmware/hvmloader/smbios.c +++ b/tools/firmware/hvmloader/smbios.c @@ -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) { diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c index 99a8e02..728966c 100644 --- a/tools/firmware/hvmloader/util.c +++ b/tools/firmware/hvmloader/util.c @@ -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 diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h index 4900150..edc2869 100644 --- a/tools/firmware/hvmloader/util.h +++ b/tools/firmware/hvmloader/util.h @@ -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); -- 2.39.5