From nobody Wed Apr 17 08:13:44 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4VKDFN6BJVz5J6ch; Wed, 17 Apr 2024 08:13:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4VKDFN3MsSz4B79; Wed, 17 Apr 2024 08:13:44 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1713341624; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=2aSGblNE1j0AvJYGXAB3fpUoCc5TMaJZ9P0ifWVeD94=; b=ZfUrCflJqT8ffhmzT6mhkg0sRLxxXU6Vo4pgneV3J9pC0rQETXlcnkQ7De7dlrlYQAKyPb KX4N0DLfcwyBSnZ+ZShPJZ8LAQ59oQEGmvMnwAxWDzoGOHCevIbAvdSa2uWXBAr3c2dP2J k4Elv2kuMx1riECiKDk1lv0PNuwqNpZ81KIqPj1A9vpS9wbY1FwpiFflXVoUXlQwWSKUn7 am5hOh+Jb8XzKHcsy+mRRtxJyslo0ag030baHU+CYj8w4xS8AJ9KNz/Xz6gVdiZqB9ptdY HYqse6UQmK78NqC6Qk9EOce5Dibiq7284dScLnWq4cWY/bfXwyaltvHfSmv0rg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1713341624; a=rsa-sha256; cv=none; b=pw6x8UXtCwtzX3yfimNdCFZMQ4bsVG6vW8V3yHpnX6YuDNq7uf8bI+Q81sdpKVp3YutOLo MRy7YbykbQcGnu+pEMXADMkEPo6ucDLm7XV0kBL/ku/KXYNi/WsRJuBcGV/v8pM6jsaOGp HQ1VaWLlH3mwo2oDm4IUNXzNhhE2+oZmVC8IVTfJwBKSTyt3PtIXTqWX0Aw6G6EpT9cf8H RVMq/hLKfkhbGSdJ5rkwvy2bgnfAmx2pEg9YYWCZXcFo7QQU581anCVQK0qbMuCfTWTNF2 IpfhxICbvd1/lk4sBym+ArMpRZqFNEDG5tB687nfjCEAhLs981QkE3GKxPg18A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1713341624; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=2aSGblNE1j0AvJYGXAB3fpUoCc5TMaJZ9P0ifWVeD94=; b=GrLciBK0+9uqZf6/Pj0uQ6D0xZJV+ypdczA9bgLFKjZxBC2FAguklqBxyBJmEKN25OAGCS 997WXTbLvOca1rxC9IuC9+W1epp7gp3/G9LB2JXX7cTCATIIRii/RkJ1T1Ep8cHdsRfOYj a5o6oJurCua9cW+QCg2leVECxbo8y9NMzc0K9LenjFHWojC/v6vsVrMeUX5lQlaCcrScrF d/dXLnY6IPCenhZmZxmH9c6Wl1CzHnlB+l/yOMyb2VwsnOdSWvq3Xk8V7NK0JEWcbqYhWP UIVlYrsswBttdhpUVs37I65EryNmu9z/+drmp3eeNp3Lx5tavbQyLo8ygvZcsA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4VKDFN30BFzJk2; Wed, 17 Apr 2024 08:13:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 43H8DiF7062466; Wed, 17 Apr 2024 08:13:44 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 43H8Di7j062463; Wed, 17 Apr 2024 08:13:44 GMT (envelope-from git) Date: Wed, 17 Apr 2024 08:13:44 GMT Message-Id: <202404170813.43H8Di7j062463@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: f95a254aa722 - stable/13 - acpidump: dump AMD IVRS table describing IOMMU layout List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: f95a254aa7226160d41768112fd714a5c16bae61 Auto-Submitted: auto-generated The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=f95a254aa7226160d41768112fd714a5c16bae61 commit f95a254aa7226160d41768112fd714a5c16bae61 Author: Konstantin Belousov AuthorDate: 2024-03-31 23:30:37 +0000 Commit: Konstantin Belousov CommitDate: 2024-04-17 08:13:18 +0000 acpidump: dump AMD IVRS table describing IOMMU layout (cherry picked from commit 6d789b6126afe1c23b65eef2c5cf4c6bd258c26f) --- usr.sbin/acpi/acpidump/acpi.c | 372 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 372 insertions(+) diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c index ec7bd65b14c9..d4ab70c9ca86 100644 --- a/usr.sbin/acpi/acpidump/acpi.c +++ b/usr.sbin/acpi/acpidump/acpi.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1496,6 +1497,375 @@ acpi_handle_dmar(ACPI_TABLE_HEADER *sdp) printf(END_COMMENT); } +static void +acpi_handle_ivrs_ivhd_header(ACPI_IVRS_HEADER *addr) +{ + printf("\n\tIVHD Type=%#x IOMMUId=%x\n\tFlags=", + addr->Type, addr->DeviceId); +#define PRINTFLAG(flag, name) printflag(addr->Flags, flag, #name) + PRINTFLAG(ACPI_IVHD_TT_ENABLE, HtTunEn); + PRINTFLAG(ACPI_IVHD_ISOC, PassPW); + PRINTFLAG(ACPI_IVHD_RES_PASS_PW, ResPassPW); + PRINTFLAG(ACPI_IVHD_ISOC, Isoc); + PRINTFLAG(ACPI_IVHD_TT_ENABLE, IotlbSup); + PRINTFLAG((1 << 5), Coherent); + PRINTFLAG((1 << 6), PreFSup); + PRINTFLAG((1 << 7), PPRSup); +#undef PRINTFLAG + PRINTFLAG_END(); +} + +static void +acpi_handle_ivrs_ivhd_dte(UINT8 dte) +{ + if (dte == 0) { + printf("\n"); + return; + } + printf(" DTE="); +#define PRINTFLAG(flag, name) printflag(dte, flag, #name) + PRINTFLAG(ACPI_IVHD_INIT_PASS, INITPass); + PRINTFLAG(ACPI_IVHD_EINT_PASS, EIntPass); + PRINTFLAG(ACPI_IVHD_NMI_PASS, NMIPass); + PRINTFLAG(ACPI_IVHD_SYSTEM_MGMT, SysMgtPass); + PRINTFLAG(ACPI_IVHD_LINT0_PASS, Lint0Pass); + PRINTFLAG(ACPI_IVHD_LINT1_PASS, Lint1Pass); +#undef PRINTFLAG + PRINTFLAG_END(); +} + +static void +acpi_handle_ivrs_ivhd_edte(UINT32 edte) +{ + if (edte == 0) + return; + printf("\t\t ExtDTE="); +#define PRINTFLAG(flag, name) printflag(edte, flag, #name) + PRINTFLAG(ACPI_IVHD_ATS_DISABLED, AtsDisabled); +#undef PRINTFLAG + PRINTFLAG_END(); +} + +static const char * +acpi_handle_ivrs_ivhd_variety(UINT8 v) +{ + switch (v) { + case ACPI_IVHD_IOAPIC: + return ("IOAPIC"); + case ACPI_IVHD_HPET: + return ("HPET"); + default: + return ("UNKNOWN"); + } +} + +static void +acpi_handle_ivrs_ivhd_devs(ACPI_IVRS_DE_HEADER *d, char *de) +{ + char *db; + ACPI_IVRS_DEVICE4 *d4; + ACPI_IVRS_DEVICE8A *d8a; + ACPI_IVRS_DEVICE8B *d8b; + ACPI_IVRS_DEVICE8C *d8c; + ACPI_IVRS_DEVICE_HID *dh; + size_t len; + UINT32 x32; + + for (; (char *)d < de; d = (ACPI_IVRS_DE_HEADER *)(db + len)) { + db = (char *)d; + if (d->Type == ACPI_IVRS_TYPE_PAD4) { + len = sizeof(*d4); + } else if (d->Type == ACPI_IVRS_TYPE_ALL) { + d4 = (ACPI_IVRS_DEVICE4 *)db; + len = sizeof(*d4); + printf("\t\tDev Type=%#x Id=ALL", d4->Header.Type); + acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting); + } else if (d->Type == ACPI_IVRS_TYPE_SELECT) { + d4 = (ACPI_IVRS_DEVICE4 *)db; + len = sizeof(*d4); + printf("\t\tDev Type=%#x Id=%#06x", d4->Header.Type, + d4->Header.Id); + acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting); + } else if (d->Type == ACPI_IVRS_TYPE_START) { + d4 = (ACPI_IVRS_DEVICE4 *)db; + len = 2 * sizeof(*d4); + printf("\t\tDev Type=%#x Id=%#06x-%#06x", + d4->Header.Type, + d4->Header.Id, (d4 + 1)->Header.Id); + acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting); + } else if (d->Type == ACPI_IVRS_TYPE_END) { + d4 = (ACPI_IVRS_DEVICE4 *)db; + len = 2 * sizeof(*d4); + printf("\t\tDev Type=%#x Id=%#06x BIOS BUG\n", + d4->Header.Type, d4->Header.Id); + } else if (d->Type == ACPI_IVRS_TYPE_PAD8) { + len = sizeof(*d8a); + } else if (d->Type == ACPI_IVRS_TYPE_ALIAS_SELECT) { + d8a = (ACPI_IVRS_DEVICE8A *)db; + len = sizeof(*d8a); + printf("\t\tDev Type=%#x Id=%#06x AliasId=%#06x", + d8a->Header.Type, d8a->Header.Id, d8a->UsedId); + acpi_handle_ivrs_ivhd_dte(d8a->Header.DataSetting); + } else if (d->Type == ACPI_IVRS_TYPE_ALIAS_START) { + d8a = (ACPI_IVRS_DEVICE8A *)db; + d4 = (ACPI_IVRS_DEVICE4 *)(db + sizeof(*d8a)); + len = sizeof(*d8a) + sizeof(*d4); + printf("\t\tDev Type=%#x Id=%#06x-%#06x AliasId=%#06x", + d8a->Header.Type, d8a->Header.Id, d4->Header.Id, + d8a->UsedId); + acpi_handle_ivrs_ivhd_dte(d8a->Header.DataSetting); + } else if (d->Type == ACPI_IVRS_TYPE_EXT_SELECT) { + d8b = (ACPI_IVRS_DEVICE8B *)db; + len = sizeof(*d8b); + printf("\t\tDev Type=%#x Id=%#06x", + d8a->Header.Type, d8a->Header.Id); + acpi_handle_ivrs_ivhd_dte(d8b->Header.DataSetting); + printf("\t\t"); + acpi_handle_ivrs_ivhd_edte(d8b->ExtendedData); + } else if (d->Type == ACPI_IVRS_TYPE_EXT_START) { + d8b = (ACPI_IVRS_DEVICE8B *)db; + len = sizeof(*d8b); + d4 = (ACPI_IVRS_DEVICE4 *)(db + sizeof(*d8a)); + len = sizeof(*d8a) + sizeof(*d4); + printf("\t\tDev Type=%#x Id=%#06x-%#06x", + d8a->Header.Type, d8a->Header.Id, d4->Header.Id); + acpi_handle_ivrs_ivhd_dte(d8b->Header.DataSetting); + acpi_handle_ivrs_ivhd_edte(d8b->ExtendedData); + } else if (d->Type == ACPI_IVRS_TYPE_SPECIAL) { + d8c = (ACPI_IVRS_DEVICE8C *)db; + len = sizeof(*d8c); + printf("\t\tDev Type=%#x Id=%#06x Handle=%#x " + "Variety=%d(%s)", + d8c->Header.Type, d8c->UsedId, d8c->Handle, + d8c->Variety, + acpi_handle_ivrs_ivhd_variety(d8c->Variety)); + acpi_handle_ivrs_ivhd_dte(d8c->Header.DataSetting); + } else if (d->Type == ACPI_IVRS_TYPE_HID) { + dh = (ACPI_IVRS_DEVICE_HID *)db; + len = sizeof(*dh) + dh->UidLength; + printf("\t\tDev Type=%#x Id=%#06x HID=", + dh->Header.Type, dh->Header.Id); + acpi_print_string((char *)&dh->AcpiHid, + sizeof(dh->AcpiHid)); + printf(" CID="); + acpi_print_string((char *)&dh->AcpiCid, + sizeof(dh->AcpiCid)); + printf(" UID="); + switch (dh->UidType) { + case ACPI_IVRS_UID_NOT_PRESENT: + default: + printf("none"); + break; + case ACPI_IVRS_UID_IS_INTEGER: + memcpy(&x32, dh + 1, sizeof(x32)); + printf("%#x", x32); + break; + case ACPI_IVRS_UID_IS_STRING: + acpi_print_string((char *)(dh + 1), + dh->UidLength); + break; + } + acpi_handle_ivrs_ivhd_dte(dh->Header.DataSetting); + } else { + printf("\t\tDev Type=%#x Unknown\n", d->Type); + if (d->Type <= 63) + len = sizeof(*d4); + else if (d->Type <= 127) + len = sizeof(*d8a); + else { + printf("Abort, cannot advance iterator.\n"); + return; + } + } + } +} + +static void +acpi_handle_ivrs_ivhd_10(ACPI_IVRS_HARDWARE1 *addr, bool efrsup) +{ + acpi_handle_ivrs_ivhd_header(&addr->Header); + printf("\tCapOffset=%#x Base=%#jx PCISeg=%#x Unit=%#x MSIlog=%d\n", + addr->CapabilityOffset, (uintmax_t)addr->BaseAddress, + addr->PciSegmentGroup, (addr->Info & ACPI_IVHD_UNIT_ID_MASK) >> 8, + addr->Info & ACPI_IVHD_MSI_NUMBER_MASK); + if (efrsup) { +#define PRINTFLAG(flag, name) printflag(addr->FeatureReporting, flag, #name) +#define PRINTFIELD(lbit, hbit, name) \ + printfield(addr->FeatureReporting, lbit, hbit, #name) + PRINTFIELD(30, 31, HATS); + PRINTFIELD(28, 29, GATS); + PRINTFIELD(23, 27, MsiNumPPR); + PRINTFIELD(17, 22, PNBanks); + PRINTFIELD(13, 16, PNCounters); + PRINTFIELD(8, 12, PASmax); + PRINTFLAG(1 << 7, HESup); + PRINTFLAG(1 << 6, GASup); + PRINTFLAG(1 << 5, UASup); + PRINTFIELD(3, 2, GLXSup); + PRINTFLAG(1 << 1, NXSup); + PRINTFLAG(1 << 0, XTSup); +#undef PRINTFLAG +#undef PRINTFIELD + PRINTFLAG_END(); + } + acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1), + (char *)addr + addr->Header.Length); +} + +static void +acpi_handle_ivrs_ivhd_info_11(ACPI_IVRS_HARDWARE2 *addr) +{ + acpi_handle_ivrs_ivhd_header(&addr->Header); + printf("\tCapOffset=%#x Base=%#jx PCISeg=%#x Unit=%#x MSIlog=%d\n", + addr->CapabilityOffset, (uintmax_t)addr->BaseAddress, + addr->PciSegmentGroup, (addr->Info >> 8) & 0x1f, + addr->Info & 0x5); + printf("\tAttr="); +#define PRINTFIELD(lbit, hbit, name) \ + printfield(addr->Attributes, lbit, hbit, #name) + PRINTFIELD(23, 27, MsiNumPPR); + PRINTFIELD(17, 22, PNBanks); + PRINTFIELD(13, 16, PNCounters); +#undef PRINTFIELD + PRINTFLAG_END(); +} + +static void +acpi_handle_ivrs_ivhd_11(ACPI_IVRS_HARDWARE2 *addr) +{ + acpi_handle_ivrs_ivhd_info_11(addr); + printf("\tEFRreg=%#018jx\n", (uintmax_t)addr->EfrRegisterImage); + acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1), + (char *)addr + addr->Header.Length); +} + +static void +acpi_handle_ivrs_ivhd_40(ACPI_IVRS_HARDWARE2 *addr) +{ + acpi_handle_ivrs_ivhd_info_11(addr); + printf("\tEFRreg=%#018jx EFR2reg=%#018jx\n", + (uintmax_t)addr->EfrRegisterImage, (uintmax_t)addr->Reserved); + acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1), + (char *)addr + addr->Header.Length); +} + +static const char * +acpi_handle_ivrs_ivmd_type(ACPI_IVRS_MEMORY *addr) +{ + switch (addr->Header.Type) { + case ACPI_IVRS_TYPE_MEMORY1: + return ("ALL"); + case ACPI_IVRS_TYPE_MEMORY2: + return ("specified"); + case ACPI_IVRS_TYPE_MEMORY3: + return ("range"); + default: + return ("unknown"); + } +} + +static void +acpi_handle_ivrs_ivmd(ACPI_IVRS_MEMORY *addr) +{ + printf("\tMem Type=%#x(%s) ", + addr->Header.Type, acpi_handle_ivrs_ivmd_type(addr)); + switch (addr->Header.Type) { + case ACPI_IVRS_TYPE_MEMORY2: + printf("Id=%#06x PCISeg=%#x ", addr->Header.DeviceId, + *(UINT16 *)&addr->Reserved); + break; + case ACPI_IVRS_TYPE_MEMORY3: + printf("Id=%#06x-%#06x PCISeg=%#x", addr->Header.DeviceId, + addr->AuxData, *(UINT16 *)&addr->Reserved); + break; + } + printf("Start=%#18jx Length=%#jx Flags=", + (uintmax_t)addr->StartAddress, (uintmax_t)addr->MemoryLength); +#define PRINTFLAG(flag, name) printflag(addr->Header.Flags, flag, #name) + PRINTFLAG(ACPI_IVMD_EXCLUSION_RANGE, ExclusionRange); + PRINTFLAG(ACPI_IVMD_WRITE, IW); + PRINTFLAG(ACPI_IVMD_READ, IR); + PRINTFLAG(ACPI_IVMD_UNITY, Unity); +#undef PRINTFLAG + PRINTFLAG_END(); +} + +static int +acpi_handle_ivrs_blocks(void *addr, int remaining, bool efrsup) +{ + ACPI_IVRS_HEADER *hdr = addr; + + if (remaining < (int)sizeof(ACPI_IVRS_HEADER)) + return (-1); + + if (remaining < hdr->Length) + return (-1); + + switch (hdr->Type) { + case ACPI_IVRS_TYPE_HARDWARE1: + acpi_handle_ivrs_ivhd_10(addr, efrsup); + break; + case ACPI_IVRS_TYPE_HARDWARE2: + if (!efrsup) + printf("\t!! Found IVHD block 0x11 but !EFRsup\n"); + acpi_handle_ivrs_ivhd_11(addr); + break; + case ACPI_IVRS_TYPE_HARDWARE3: + if (!efrsup) + printf("\t!! Found IVHD block 0x40 but !EFRsup\n"); + acpi_handle_ivrs_ivhd_40(addr); + break; + case ACPI_IVRS_TYPE_MEMORY1: + case ACPI_IVRS_TYPE_MEMORY2: + case ACPI_IVRS_TYPE_MEMORY3: + acpi_handle_ivrs_ivmd(addr); + break; + default: + printf("\n"); + printf("\tType=%d\n", hdr->Type); + printf("\tLength=%d\n", hdr->Length); + break; + } + return (hdr->Length); +} + +#define ACPI_IVRS_DMAREMAP 0x00000002 +#define ACPI_IVRS_EFRSUP 0x00000001 +#define ACPI_IVRS_GVA_SIZE 0x000000e0 + +static void +acpi_handle_ivrs(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_IVRS *ivrs; + char *cp; + int remaining, consumed; + bool efrsup; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + ivrs = (ACPI_TABLE_IVRS *)sdp; + efrsup = (ivrs->Info & ACPI_IVRS_EFRSUP) != 0; + printf("\tVAsize=%d PAsize=%d GVAsize=%d\n", + (ivrs->Info & ACPI_IVRS_VIRTUAL_SIZE) >> 15, + (ivrs->Info & ACPI_IVRS_PHYSICAL_SIZE) >> 8, + (ivrs->Info & ACPI_IVRS_GVA_SIZE) >> 5); + printf("\tATS_resp_res=%d DMA_preboot_remap=%d EFRsup=%d\n", + (ivrs->Info & ACPI_IVRS_ATS_RESERVED) != 0, + (ivrs->Info & ACPI_IVRS_DMAREMAP) != 0, efrsup); + + remaining = sdp->Length - sizeof(ACPI_TABLE_IVRS); + while (remaining > 0) { + cp = (char *)sdp + sdp->Length - remaining; + consumed = acpi_handle_ivrs_blocks(cp, remaining, efrsup); + if (consumed <= 0) + break; + else + remaining -= consumed; + } + + printf(END_COMMENT); +} + static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp) { @@ -2086,6 +2456,8 @@ acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp) acpi_handle_tcpa(sdp); else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4)) acpi_handle_dmar(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_IVRS, 4)) + acpi_handle_ivrs(sdp); else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4)) acpi_handle_nfit(sdp); else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))