From owner-svn-src-stable@freebsd.org Thu Oct 1 20:54:20 2015 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 74EBCA0CE9F; Thu, 1 Oct 2015 20:54:20 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 596EE1E9A; Thu, 1 Oct 2015 20:54:20 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t91KsKkf093633; Thu, 1 Oct 2015 20:54:20 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t91KsKtk093632; Thu, 1 Oct 2015 20:54:20 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201510012054.t91KsKtk093632@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Thu, 1 Oct 2015 20:54:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r288461 - stable/10/sys/x86/acpica X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Oct 2015 20:54:20 -0000 Author: jhb Date: Thu Oct 1 20:54:19 2015 New Revision: 288461 URL: https://svnweb.freebsd.org/changeset/base/288461 Log: MFC 284175: Handle X2APIC entries in the MADT for APICs with an ID < 255. At least one BIOS has been seen to include such entries even though the relevant specs require that X2APIC entries only be used for CPUs with an APIC ID >= 255. This was tested on a system with "plain" local APIC entries in the MADT to ensure no regressions, but it has not yet been tested on a system with X2APIC entries in the MADT. Currently such systems do not boot at all, and with this change they might now boot correctly. Modified: stable/10/sys/x86/acpica/madt.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/x86/acpica/madt.c ============================================================================== --- stable/10/sys/x86/acpica/madt.c Thu Oct 1 20:49:10 2015 (r288460) +++ stable/10/sys/x86/acpica/madt.c Thu Oct 1 20:54:19 2015 (r288461) @@ -53,8 +53,8 @@ static struct { } *ioapics; static struct lapic_info { - u_int la_enabled:1; - u_int la_acpi_id:8; + u_int la_enabled; + u_int la_acpi_id; } lapics[MAX_APIC_ID + 1]; static int madt_found_sci_override; @@ -220,34 +220,48 @@ madt_walk_table(acpi_subtable_handler *h } static void +madt_add_cpu(u_int acpi_id, u_int apic_id, u_int flags) +{ + struct lapic_info *la; + + /* + * The MADT does not include a BSP flag, so we have to let the + * MP code figure out which CPU is the BSP on its own. + */ + if (bootverbose) + printf("MADT: Found CPU APIC ID %u ACPI ID %u: %s\n", + apic_id, acpi_id, flags & ACPI_MADT_ENABLED ? + "enabled" : "disabled"); + if (!(flags & ACPI_MADT_ENABLED)) + return; + if (apic_id > MAX_APIC_ID) { + printf("MADT: Ignoring local APIC ID %u (too high)\n", + apic_id); + return; + } + + la = &lapics[apic_id]; + KASSERT(la->la_enabled == 0, ("Duplicate local APIC ID %u", apic_id)); + la->la_enabled = 1; + la->la_acpi_id = acpi_id; + lapic_create(apic_id, 0); +} + +static void madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg) { ACPI_MADT_LOCAL_APIC *proc; - struct lapic_info *la; + ACPI_MADT_LOCAL_X2APIC *x2apic; switch (entry->Type) { case ACPI_MADT_TYPE_LOCAL_APIC: - /* - * The MADT does not include a BSP flag, so we have to - * let the MP code figure out which CPU is the BSP on - * its own. - */ proc = (ACPI_MADT_LOCAL_APIC *)entry; - if (bootverbose) - printf("MADT: Found CPU APIC ID %u ACPI ID %u: %s\n", - proc->Id, proc->ProcessorId, - (proc->LapicFlags & ACPI_MADT_ENABLED) ? - "enabled" : "disabled"); - if (!(proc->LapicFlags & ACPI_MADT_ENABLED)) - break; - if (proc->Id > MAX_APIC_ID) - panic("%s: CPU ID %u too high", __func__, proc->Id); - la = &lapics[proc->Id]; - KASSERT(la->la_enabled == 0, - ("Duplicate local APIC ID %u", proc->Id)); - la->la_enabled = 1; - la->la_acpi_id = proc->ProcessorId; - lapic_create(proc->Id, 0); + madt_add_cpu(proc->ProcessorId, proc->Id, proc->LapicFlags); + break; + case ACPI_MADT_TYPE_LOCAL_X2APIC: + x2apic = (ACPI_MADT_LOCAL_X2APIC *)entry; + madt_add_cpu(x2apic->Uid, x2apic->LocalApicId, + x2apic->LapicFlags); break; } } @@ -503,29 +517,44 @@ madt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi * Parse an entry for an NMI routed to a local APIC LVT pin. */ static void -madt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi) +madt_handle_local_nmi(u_int acpi_id, UINT8 Lint, UINT16 IntiFlags) { u_int apic_id, pin; - if (nmi->ProcessorId == 0xff) + if (acpi_id == 0xffffffff) apic_id = APIC_ID_ALL; - else if (madt_find_cpu(nmi->ProcessorId, &apic_id) != 0) { + else if (madt_find_cpu(acpi_id, &apic_id) != 0) { if (bootverbose) printf("MADT: Ignoring local NMI routed to " - "ACPI CPU %u\n", nmi->ProcessorId); + "ACPI CPU %u\n", acpi_id); return; } - if (nmi->Lint == 0) + if (Lint == 0) pin = APIC_LVT_LINT0; else pin = APIC_LVT_LINT1; lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI); - if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS)) + if (!(IntiFlags & ACPI_MADT_TRIGGER_CONFORMS)) lapic_set_lvt_triggermode(apic_id, pin, - interrupt_trigger(nmi->IntiFlags, 0)); - if (!(nmi->IntiFlags & ACPI_MADT_POLARITY_CONFORMS)) + interrupt_trigger(IntiFlags, 0)); + if (!(IntiFlags & ACPI_MADT_POLARITY_CONFORMS)) lapic_set_lvt_polarity(apic_id, pin, - interrupt_polarity(nmi->IntiFlags, 0)); + interrupt_polarity(IntiFlags, 0)); +} + +static void +madt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi) +{ + + madt_handle_local_nmi(nmi->ProcessorId == 0xff ? 0xffffffff : + nmi->ProcessorId, nmi->Lint, nmi->IntiFlags); +} + +static void +madt_parse_local_x2apic_nmi(ACPI_MADT_LOCAL_X2APIC_NMI *nmi) +{ + + madt_handle_local_nmi(nmi->Uid, nmi->Lint, nmi->IntiFlags); } /* @@ -546,6 +575,10 @@ madt_parse_ints(ACPI_SUBTABLE_HEADER *en case ACPI_MADT_TYPE_LOCAL_APIC_NMI: madt_parse_local_nmi((ACPI_MADT_LOCAL_APIC_NMI *)entry); break; + case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: + madt_parse_local_x2apic_nmi( + (ACPI_MADT_LOCAL_X2APIC_NMI *)entry); + break; } }