From: Shannon Zhao Date: Wed, 2 Mar 2016 07:35:00 +0000 (+0100) Subject: acpi/table: Introduce acpi_table_get_entry_madt to get specified entry X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=9b4e61b7e642659a35c9b6189a0c164879756fad;p=people%2Fliuw%2Fxen.git acpi/table: Introduce acpi_table_get_entry_madt to get specified entry This function could get the specified index entry of MADT table. This would be useful when it needs to get the contens of the entry. Signed-off-by: Shannon Zhao Acked-by: Jan Beulich --- diff --git a/xen/drivers/acpi/tables.c b/xen/drivers/acpi/tables.c index 56fa71b8f9..dd2031f36a 100644 --- a/xen/drivers/acpi/tables.c +++ b/xen/drivers/acpi/tables.c @@ -223,6 +223,65 @@ void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) } } +static struct acpi_subtable_header * __init +acpi_get_entry(const char *id, unsigned long table_size, + const struct acpi_table_header *table_header, + enum acpi_madt_type entry_id, unsigned int entry_index) +{ + struct acpi_subtable_header *entry; + int count = 0; + unsigned long table_end; + + if (!table_size) + return NULL; + + if (!table_header) { + printk(KERN_WARNING PREFIX "%4.4s not present\n", id); + return NULL; + } + + table_end = (unsigned long)table_header + table_header->length; + + /* Parse all entries looking for a match. */ + entry = (void *)table_header + table_size; + + while ((unsigned long)(entry + 1) < table_end) { + if (entry->length < sizeof(*entry)) { + printk(KERN_ERR PREFIX "[%4.4s:%#x] Invalid length\n", + id, entry_id); + return NULL; + } + + if (entry->type == entry_id) { + if (count == entry_index) + return entry; + count++; + } + + entry = (void *)entry + entry->length; + } + + return NULL; +} + +struct acpi_subtable_header * __init +acpi_table_get_entry_madt(enum acpi_madt_type entry_id, + unsigned int entry_index) +{ + struct acpi_table_header *table_header; + acpi_status status; + + status = acpi_get_table(ACPI_SIG_MADT, acpi_apic_instance, + &table_header); + if (ACPI_FAILURE(status)) { + printk(KERN_WARNING PREFIX "%4.4s not present\n", + ACPI_SIG_MADT); + return NULL; + } + + return acpi_get_entry(ACPI_SIG_MADT, sizeof(struct acpi_table_madt), + table_header, entry_id, entry_index); +} int __init acpi_parse_entries(char *id, unsigned long table_size, diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h index 31a6918bf4..7a5abbe712 100644 --- a/xen/include/xen/acpi.h +++ b/xen/include/xen/acpi.h @@ -80,6 +80,8 @@ int acpi_parse_entries(char *id, unsigned long table_size, int entry_id, unsigned int max_entries); int acpi_table_parse_entries(char *id, unsigned long table_size, int entry_id, acpi_table_entry_handler handler, unsigned int max_entries); +struct acpi_subtable_header *acpi_table_get_entry_madt(enum acpi_madt_type id, + unsigned int entry_index); int acpi_table_parse_madt(enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries); int acpi_table_parse_srat(int id, acpi_madt_entry_handler handler, unsigned int max_entries);