From nobody Fri Dec 19 06:17:46 2025 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 78.46.105.101 is neither permitted nor denied by domain of seabios.org) client-ip=78.46.105.101; envelope-from=seabios-bounces@seabios.org; helo=coreboot.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=none (zohomail.com: 78.46.105.101 is neither permitted nor denied by domain of seabios.org) smtp.mailfrom=seabios-bounces@seabios.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1585902723; cv=none; d=zohomail.com; s=zohoarc; b=AkSYBbZL4bu1M1RRJ6jQhD/9ZfchayhrUpkkd7U1Y/BBwAGY0Sq2ynJvjMAWTzy9AeIQI/o7wvk3p9IT7Bku9+qjtB1Q2xTuylA56KV1i7Sl0v+uX53lkFnBrTg7i3t23uTYi7A0vVozqDRnpLU6UIlaLMBolKwVtv+P6oGjF3I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1585902723; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Subject:To; bh=Yz27HmMXoNn7BZj1gyHI41DOYXWtBfxRavxP/G9OLHA=; b=OZUvAeRhw4L4rm3tFNALf9sn8hff5f6A1pqTDOv+JKTIfTe2zrIEP9gRPlH7p4+XsFbneeXSl/ot6CzaxJ9UguBzzq5UGw5ZgdXRqeLWmMdpYF0ZeYMyd32cS8rTHyj69gOP/rUMvpo0CuErDghIiuy3XHL7PlDcbW9aSaQIeKQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=none (zohomail.com: 78.46.105.101 is neither permitted nor denied by domain of seabios.org) smtp.mailfrom=seabios-bounces@seabios.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from coreboot.org (coreboot.org [78.46.105.101]) by mx.zohomail.com with SMTPS id 15859027236888.353319551894742; Fri, 3 Apr 2020 01:32:03 -0700 (PDT) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTPA id 01578B01A28; Fri, 3 Apr 2020 08:31:59 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTP id 036ADB00165 for ; Fri, 3 Apr 2020 08:31:45 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-391-gH7nl_veOtK09IeFJ6xKJQ-1; Fri, 03 Apr 2020 04:31:41 -0400 Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id F23AF107ACC9 for ; Fri, 3 Apr 2020 08:31:40 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by smtp.corp.redhat.com (Postfix) with ESMTP id E3C6C396; Fri, 3 Apr 2020 08:31:39 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) id AC5F017516; Fri, 3 Apr 2020 10:31:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1585902705; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8pBBGt1w9CMsLiistmVD+jqwxNqE9/clvVwvVAPH6hc=; b=Fmui1IbVuJJTLl93DGfPtJqfh/JaskhtcRVjnOE4L04OWOSxBT/JsXDyFPF4DJR0rvKjAr 7fEV5GUHNIt/GjMs85roQGuXZdkCVHkFL6/MRwcSUQuKZM+BgloabDwgmOf6g6WkELW4RH U3+cRffLuPsFYZzn4AjosFmZtMLHIXA= X-MC-Unique: gH7nl_veOtK09IeFJ6xKJQ-1 From: Gerd Hoffmann To: seabios@seabios.org Date: Fri, 3 Apr 2020 10:31:19 +0200 Message-Id: <20200403083121.10766-8-kraxel@redhat.com> In-Reply-To: <20200403083121.10766-1-kraxel@redhat.com> References: <20200403083121.10766-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: SNRIP43BECGXY2MPSLU6PZPYOJPOHLAR X-Message-ID-Hash: SNRIP43BECGXY2MPSLU6PZPYOJPOHLAR X-MailFrom: kraxel@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-seabios.seabios.org-0; header-match-seabios.seabios.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Gerd Hoffmann X-Mailman-Version: 3.3.1 Precedence: list Subject: [SeaBIOS] [PATCH 7/9] acpi: add dsdt parser List-Id: SeaBIOS mailing list Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Spamd-Bar: ++++ X-Spam-Level: **** Authentication-Results: coreboot.org; auth=pass smtp.auth=mailman@coreboot.org smtp.mailfrom=seabios-bounces@seabios.org X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Create a list of devices found in the DSDT table. Add helper functions to find devices, walk the list and figure device informations like mmio ranges and irqs. Signed-off-by: Gerd Hoffmann --- src/util.h | 10 + src/fw/biostables.c | 622 ++++++++++++++++++++++++++++++++++++++++++++ src/post.c | 2 + src/Kconfig | 7 + 4 files changed, 641 insertions(+) diff --git a/src/util.h b/src/util.h index 4f27fc307439..8ee0370492b8 100644 --- a/src/util.h +++ b/src/util.h @@ -94,6 +94,16 @@ void display_uuid(void); void copy_table(void *pos); void smbios_setup(void); =20 +struct acpi_device; +void acpi_dsdt_parse(void); +struct acpi_device *acpi_dsdt_find_string(struct acpi_device *prev, const = char *hid); +struct acpi_device *acpi_dsdt_find_eisaid(struct acpi_device *prev, u16 ei= said); +char *acpi_dsdt_name(struct acpi_device *dev); +int acpi_dsdt_present_eisaid(u16 eisaid); +int acpi_dsdt_find_io(struct acpi_device *dev, u64 *min, u64 *max); +int acpi_dsdt_find_mem(struct acpi_device *dev, u64 *min, u64 *max); +int acpi_dsdt_find_irq(struct acpi_device *dev, u64 *irq); + // fw/coreboot.c extern const char *CBvendor, *CBpart; struct cbfs_file; diff --git a/src/fw/biostables.c b/src/fw/biostables.c index 0d4fdb9c22e8..ebe1c90fca5e 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -17,6 +17,7 @@ #include "std/smbios.h" // struct smbios_entry_point #include "string.h" // memcpy #include "util.h" // copy_table +#include "list.h" // hlist_* #include "x86.h" // outb =20 struct pir_header *PirAddr VARFSEG; @@ -509,3 +510,624 @@ copy_table(void *pos) copy_acpi_rsdp(pos); copy_smbios(pos); } + +/**************************************************************** + * DSDT parser + ****************************************************************/ + +struct acpi_device { + struct hlist_node node; + char name[16]; + u8 *hid_aml; + u8 *sta_aml; + u8 *crs_data; + int crs_size; +}; +static struct hlist_head acpi_devices; + +static int parse_error =3D 0; +static int parse_dumptree =3D 0; +static char parse_name[32]; +static struct acpi_device *parse_dev; + +static void parse_termlist(u8 *ptr, int offset, int pkglength); + +static void hex(const u8 *ptr, int count, int lvl, const char *item) +{ + int l =3D 0, i; + + do { + dprintf(lvl, "%s: %04x: ", item, l); + for (i =3D l; i < l+16; i +=3D 4) + dprintf(lvl, "%02x %02x %02x %02x ", + ptr[i+0], ptr[i+1], ptr[i+2], ptr[i+3]); + for (i =3D l; i < l+16; i++) + dprintf(lvl, "%c", (ptr[i] > 0x20 && ptr[i] < 0x80) ? ptr[i] := '.'); + dprintf(lvl, "\n"); + l +=3D 16; + } while (l < count); +} + +static u64 parse_resource_int(u8 *ptr, int count) +{ + u64 value =3D 0; + int index =3D 0; + + for (index =3D 0; index < count; index++) + value |=3D (u64)ptr[index] << (index * 8); + return value; +} + +static int parse_resource_bit(u8 *ptr, int count) +{ + int bit; + + for (bit =3D 0; bit < count*8; bit++) + if (ptr[bit/8] & (1 << (bit%8))) + return bit; + return 0; +} + +static int parse_resource(u8 *ptr, int length, int *type, u64 *min, u64 *m= ax) +{ + int rname, rsize; + u64 len; + + *type =3D -1; + *min =3D 0; + *max =3D 0; + len =3D 0; + if (!(ptr[0] & 0x80)) { + /* small resource */ + rname =3D (ptr[0] >> 3) & 0x0f; + rsize =3D ptr[0] & 0x07; + rsize++; + switch (rname) { + case 0x04: /* irq */ + *min =3D parse_resource_bit(ptr + 1, rsize); + *max =3D *min; + *type =3D 3; + break; + case 0x0f: /* end marker */ + return 0; + case 0x08: /* io */ + *min =3D parse_resource_int(ptr + 2, 2); + *max =3D parse_resource_int(ptr + 4, 2); + if (*min =3D=3D *max) { + *max =3D *min + ptr[7] - 1; + *type =3D 1; + } + break; + case 0x09: /* fixed io */ + *min =3D parse_resource_int(ptr + 2, 2); + *max =3D *min + ptr[4] - 1; + *type =3D 1; + break; + default: + dprintf(3, "%s: small: 0x%x (len %d)\n", + __func__, rname, rsize); + break; + } + } else { + /* large resource */ + rname =3D ptr[0] & 0x7f; + rsize =3D ptr[2] << 8 | ptr[1]; + rsize +=3D 3; + switch (rname) { + case 0x06: /* 32-bit Fixed Location Memory Range Descriptor */ + *min =3D parse_resource_int(ptr + 4, 4); + len =3D parse_resource_int(ptr + 8, 4); + *max =3D *min + len - 1; + *type =3D 0; + break; + case 0x07: /* DWORD Address Space Descriptor */ + *min =3D parse_resource_int(ptr + 10, 4); + *max =3D parse_resource_int(ptr + 14, 4); + *type =3D ptr[3]; + break; + case 0x08: /* WORD Address Space Descriptor */ + *min =3D parse_resource_int(ptr + 8, 2); + *max =3D parse_resource_int(ptr + 10, 2); + *type =3D ptr[3]; + break; + case 0x09: /* irq */ + *min =3D parse_resource_int(ptr + 5, 4); + *max =3D *min; + *type =3D 3; + break; + case 0x0a: /* QWORD Address Space Descriptor */ + *min =3D parse_resource_int(ptr + 14, 8); + *max =3D parse_resource_int(ptr + 22, 8); + *type =3D ptr[3]; + break; + default: + dprintf(3, "%s: large: 0x%x (len %d)\n", __func__, rname, rsiz= e); + break; + } + } + return rsize; +} + +static int find_resource(u8 *ptr, int len, int kind, u64 *min, u64 *max) +{ + int type, size, offset =3D 0; + + do { + size =3D parse_resource(ptr + offset, len - offset, + &type, min, max); + if (kind =3D=3D type) + return 0; + offset +=3D size; + } while (size > 0 && offset < len); + return -1; +} + +static int print_resources(const char *prefix, u8 *ptr, int len) +{ + static const char *typename[] =3D { "mem", "i/o", "bus" }; + int type, size, offset =3D 0; + u64 min, max; + + do { + size =3D parse_resource(ptr + offset, len - offset, + &type, &min, &max); + switch (type) { + case 0: + case 1: + case 2: + dprintf(1, "%s%s 0x%llx -> 0x%llx\n", + prefix, typename[type], min, max); + break; + case 3: + dprintf(1, "%sirq %lld\n", prefix, min); + break; + } + offset +=3D size; + } while (size > 0 && offset < len); + return -1; +} + +static int parse_nameseg(u8 *ptr, char **dst) +{ + if (dst && *dst) { + *(dst[0]++) =3D ptr[0]; + if (ptr[1] !=3D '_') + *(dst[0]++) =3D ptr[1]; + if (ptr[2] !=3D '_') + *(dst[0]++) =3D ptr[2]; + if (ptr[3] !=3D '_') + *(dst[0]++) =3D ptr[3]; + *(dst[0]) =3D 0; + } + return 4; +} + +static int parse_namestring(u8 *ptr, const char *item) +{ + char *dst =3D parse_name; + int offset =3D 0; + int i, count; + +again: + switch (ptr[offset]) { + case 0: /* null name */ + offset++; + *(dst++) =3D 0; + break; + case 0x2e: + offset++; + offset +=3D parse_nameseg(ptr + offset, &dst); + *(dst++) =3D '.'; + offset +=3D parse_nameseg(ptr + offset, &dst); + break; + case 0x2f: + offset++; + count =3D ptr[offset]; + offset++; + for (i =3D 0; i < count; i++) { + if (i) + *(dst++) =3D '.'; + offset +=3D parse_nameseg(ptr + offset, &dst); + } + break; + case '\\': + *(dst++) =3D '\\'; + offset++; + goto again; + case '^': + *(dst++) =3D '^'; + offset++; + goto again; + case 'A' ... 'Z': + case '_': + offset +=3D parse_nameseg(ptr, &dst); + break; + default: + hex(ptr, 16, 3, __func__); + parse_error =3D 1; + break; + } + dprintf(5, "%s: %s '%s'\n", __func__, item, parse_name); + return offset; +} + +static int parse_termarg_int(u8 *ptr, u64 *dst) +{ + u64 value; + int offset =3D 1; + + switch (ptr[0]) { + case 0x00: /* zero */ + value =3D 0; + break; + case 0x01: /* one */ + value =3D 1; + break; + case 0x0a: /* byte prefix */ + value =3D ptr[1]; + offset++; + break; + case 0x0b: /* word prefix */ + value =3D ptr[1] | + ((unsigned long)ptr[2] << 8); + offset +=3D 2; + break; + case 0x0c: /* dword prefix */ + value =3D ptr[1] | + ((unsigned long)ptr[2] << 8) | + ((unsigned long)ptr[3] << 16) | + ((unsigned long)ptr[4] << 24); + offset +=3D 4; + break; + default: + value =3D 0; + hex(ptr, 16, 3, __func__); + parse_error =3D 1; + break; + } + + if (dst) + *dst =3D value; + dprintf(5, "%s: 0x%llx\n", __func__, value); + return offset; +} + +static int parse_pkglength(u8 *ptr, int *pkglength) +{ + int offset =3D 2; + + *pkglength =3D 0; + switch (ptr[0] >> 6) { + case 3: + *pkglength |=3D ptr[3] << 20; + offset++; + case 2: + *pkglength |=3D ptr[2] << 12; + offset++; + case 1: + *pkglength |=3D ptr[1] << 4; + *pkglength |=3D ptr[0] & 0x0f; + return offset; + case 0: + default: + *pkglength |=3D ptr[0] & 0x3f; + return 1; + } +} + +static int parse_pkg_common(u8 *ptr, const char *item, int *pkglength) +{ + int offset; + + offset =3D parse_pkglength(ptr, pkglength); + offset +=3D parse_namestring(ptr + offset, item); + return offset; +} + +static int parse_pkg_scope(u8 *ptr) +{ + int offset, pkglength; + + offset =3D parse_pkg_common(ptr, "skope", &pkglength); + parse_termlist(ptr, offset, pkglength); + return pkglength; +} + +static int parse_pkg_device(u8 *ptr) +{ + int offset, pkglength; + + offset =3D parse_pkg_common(ptr, "device", &pkglength); + + parse_dev =3D malloc_high(sizeof(*parse_dev)); + if (!parse_dev) { + warn_noalloc(); + parse_error =3D 1; + return pkglength; + } + + memset(parse_dev, 0, sizeof(*parse_dev)); + hlist_add_head(&parse_dev->node, &acpi_devices); + strtcpy(parse_dev->name, parse_name, sizeof(parse_dev->name)); + + parse_termlist(ptr, offset, pkglength); + return pkglength; +} + +static int parse_pkg_buffer(u8 *ptr) +{ + u64 blen; + int pkglength, offset; + + offset =3D parse_pkglength(ptr, &pkglength); + offset +=3D parse_termarg_int(ptr + offset, &blen); + if (strcmp(parse_name, "_CRS") =3D=3D 0) { + parse_dev->crs_data =3D ptr + offset; + parse_dev->crs_size =3D blen; + } + return pkglength; +} + +static int parse_pkg_skip(u8 *ptr, int op, int name) +{ + int pkglength, offset; + char item[8]; + + snprintf(item, sizeof(item), "op %x", op); + offset =3D parse_pkglength(ptr, &pkglength); + if (name) { + parse_namestring(ptr + offset, item); + } else { + dprintf(5, "%s: %s (%d)\n", __func__, item, pkglength); + } + return pkglength; +} + +static int parse_termobj(u8 *ptr) +{ + int offset =3D 1; + + switch (ptr[0]) { + case 0x00: /* zero */ + break; + case 0x01: /* one */ + break; + case 0x08: /* name op */ + offset +=3D parse_namestring(ptr + offset, "name"); + offset +=3D parse_termobj(ptr + offset); + if (strcmp(parse_name, "_HID") =3D=3D 0) + parse_dev->hid_aml =3D ptr; + if (strcmp(parse_name, "_STA") =3D=3D 0) + parse_dev->sta_aml =3D ptr; + break; + case 0x0a: /* byte prefix */ + offset++; + break; + case 0x0b: /* word prefix */ + offset +=3D 2; + break; + case 0x0c: /* dword prefix */ + offset +=3D 4; + break; + case 0x0d: /* string prefix */ + while (ptr[offset]) + offset++; + offset++; + break; + case 0x10: /* scope op */ + offset +=3D parse_pkg_scope(ptr + offset); + break; + case 0x11: /* buffer op */ + offset +=3D parse_pkg_buffer(ptr + offset); + break; + case 0x12: /* package op */ + case 0x13: /* var package op */ + offset +=3D parse_pkg_skip(ptr + offset, ptr[0], 0); + break; + case 0x14: /* method op */ + offset +=3D parse_pkg_skip(ptr + offset, ptr[0], 1); + if (strcmp(parse_name, "_STA") =3D=3D 0) + parse_dev->sta_aml =3D ptr; + break; + case 0x5b: /* ext op prefix */ + offset++; + switch (ptr[1]) { + case 0x01: /* mutex op */ + offset +=3D parse_namestring(ptr + offset, "mutex"); + offset++; /* sync flags */ + break; + case 0x80: /* op region op */ + offset +=3D parse_namestring(ptr + offset, "op region"); + offset++; /* region space */ + offset +=3D parse_termarg_int(ptr + offset, NULL); + offset +=3D parse_termarg_int(ptr + offset, NULL); + break; + case 0x81: /* field op */ + case 0x83: /* processor op */ + case 0x84: /* power resource op */ + case 0x85: /* thermal zone op */ + offset +=3D parse_pkg_skip(ptr + offset, 0x5b00 | ptr[1], 1); + break; + case 0x82: /* device op */ + offset +=3D parse_pkg_device(ptr + offset); + break; + default: + hex(ptr, 16, 3, __func__); + parse_error =3D 1; + break; + } + break; + default: + hex(ptr, 16, 3, __func__); + parse_error =3D 1; + break; + } + + return offset; +} + +static void parse_termlist(u8 *ptr, int offset, int pkglength) +{ + for (;;) { + offset +=3D parse_termobj(ptr + offset); + if (offset =3D=3D pkglength) + return; + if (offset > pkglength) { + dprintf(1, "%s: overrun: %d/%d\n", __func__, + offset, pkglength); + parse_error =3D 1; + return; + } + if (parse_error) { + dprintf(1, "%s: parse error, skip from %d/%d\n", __func__, + offset, pkglength); + parse_error =3D 0; + return; + } + } +} + +static struct acpi_device *acpi_dsdt_find(struct acpi_device *prev, const = u8 *aml, int size) +{ + struct acpi_device *dev; + struct hlist_node *node; + + if (!prev) + node =3D acpi_devices.first; + else + node =3D prev->node.next; + + for (; node !=3D NULL; node =3D dev->node.next) { + dev =3D container_of(node, struct acpi_device, node); + if (!aml) + return dev; + if (!dev->hid_aml) + continue; + if (memcmp(dev->hid_aml + 5, aml, size) =3D=3D 0) + return dev; + } + return NULL; +} + +static int acpi_dsdt_present(struct acpi_device *dev) +{ + if (!dev) + return 0; /* no */ + if (!dev->sta_aml) + return 1; /* yes */ + if (dev->sta_aml[0] =3D=3D 0x14) + return -1; /* unknown (can't evaluate method) */ + if (dev->sta_aml[0] =3D=3D 0x08) { + u64 value =3D 0; + parse_termarg_int(dev->sta_aml + 5, &value); + if (value =3D=3D 0) + return 0; /* no */ + else + return 1; /* yes */ + } + return -1; /* unknown (should not happen) */ +} + +/**************************************************************** + * DSDT parser, public interface + ****************************************************************/ + +struct acpi_device *acpi_dsdt_find_string(struct acpi_device *prev, const = char *hid) +{ + if (!CONFIG_ACPI_PARSE) + return NULL; + + u8 aml[10]; + int len =3D snprintf((char*)aml, sizeof(aml), "\x0d%s", hid); + return acpi_dsdt_find(prev, aml, len); +} + +struct acpi_device *acpi_dsdt_find_eisaid(struct acpi_device *prev, u16 ei= said) +{ + if (!CONFIG_ACPI_PARSE) + return NULL; + u8 aml[] =3D { + 0x0c, 0x41, 0xd0, + eisaid >> 8, + eisaid & 0xff + }; + return acpi_dsdt_find(prev, aml, 5); +} + +char *acpi_dsdt_name(struct acpi_device *dev) +{ + if (!CONFIG_ACPI_PARSE || !dev) + return NULL; + return dev->name; +} + +int acpi_dsdt_find_io(struct acpi_device *dev, u64 *min, u64 *max) +{ + if (!CONFIG_ACPI_PARSE || !dev || !dev->crs_data) + return -1; + return find_resource(dev->crs_data, dev->crs_size, + 1 /* I/O */, min, max); +} + +int acpi_dsdt_find_mem(struct acpi_device *dev, u64 *min, u64 *max) +{ + if (!CONFIG_ACPI_PARSE || !dev || !dev->crs_data) + return -1; + return find_resource(dev->crs_data, dev->crs_size, + 0 /* mem */, min, max); +} + +int acpi_dsdt_find_irq(struct acpi_device *dev, u64 *irq) +{ + u64 max; + if (!CONFIG_ACPI_PARSE || !dev || !dev->crs_data) + return -1; + return find_resource(dev->crs_data, dev->crs_size, + 3 /* irq */, irq, &max); +} + +int acpi_dsdt_present_eisaid(u16 eisaid) +{ + if (!CONFIG_ACPI_PARSE) + return -1; /* unknown */ + + struct acpi_device *dev =3D acpi_dsdt_find_eisaid(NULL, eisaid); + return acpi_dsdt_present(dev); +} + +void acpi_dsdt_parse(void) +{ + if (!CONFIG_ACPI_PARSE) + return; + + struct fadt_descriptor_rev1 *fadt =3D find_acpi_table(FACP_SIGNATURE); + if (!fadt) + return; + u8 *dsdt =3D (void*)(fadt->dsdt); + if (!dsdt) + return; + + u32 length =3D *(u32*)(dsdt + 4); + u32 offset =3D 0x24; + dprintf(1, "ACPI: parse DSDT at %p (len %d)\n", dsdt, length); + parse_termlist(dsdt, offset, length); + + if (parse_dumptree) { + struct acpi_device *dev; + dprintf(1, "ACPI: dumping dsdt devices\n"); + for (dev =3D acpi_dsdt_find(NULL, NULL, 0); + dev !=3D NULL; + dev =3D acpi_dsdt_find(dev, NULL, 0)) { + dprintf(1, " %s", acpi_dsdt_name(dev)); + if (dev->hid_aml) + dprintf(1, ", hid"); + if (dev->sta_aml) + dprintf(1, ", sta (0x%x)", dev->sta_aml[0]); + if (dev->crs_data) + dprintf(1, ", crs"); + dprintf(1, "\n"); + if (dev->crs_data) + print_resources(" ", dev->crs_data, dev->crs_size); + } + } +} diff --git a/src/post.c b/src/post.c index f93106a1c9c9..febdc0859764 100644 --- a/src/post.c +++ b/src/post.c @@ -149,6 +149,8 @@ platform_hardware_setup(void) qemu_platform_setup(); coreboot_platform_setup(); =20 + acpi_dsdt_parse(); + // Setup timers and periodic clock interrupt timer_setup(); clock_setup(); diff --git a/src/Kconfig b/src/Kconfig index 6606ce4d46c9..ab36e676bf12 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -524,6 +524,13 @@ menu "BIOS Tables" This option can be disabled for QEMU 1.6 and older to save some space in the ROM file. If unsure, say Y. + config ACPI_PARSE + bool "Include ACPI DSDT parser." + default n + help + Support parsing ACPI DSDT for device probing. + Needed to find virtio-mmio devices. + If unsure, say N. endmenu =20 source vgasrc/Kconfig --=20 2.18.2 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org