[Midnightbsd-cvs] src [12312] trunk/sys/x86: sync with FreeBSD 11-stable

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Feb 8 14:34:35 EST 2020


Revision: 12312
          http://svnweb.midnightbsd.org/src/?rev=12312
Author:   laffer1
Date:     2020-02-08 14:34:34 -0500 (Sat, 08 Feb 2020)
Log Message:
-----------
sync with FreeBSD 11-stable

Modified Paths:
--------------
    trunk/sys/x86/acpica/OsdEnvironment.c
    trunk/sys/x86/acpica/acpi_apm.c
    trunk/sys/x86/acpica/acpi_wakeup.c
    trunk/sys/x86/acpica/madt.c
    trunk/sys/x86/acpica/srat.c
    trunk/sys/x86/bios/smbios.c
    trunk/sys/x86/bios/vpd.c
    trunk/sys/x86/cpufreq/est.c
    trunk/sys/x86/cpufreq/hwpstate.c
    trunk/sys/x86/cpufreq/p4tcc.c
    trunk/sys/x86/cpufreq/powernow.c
    trunk/sys/x86/cpufreq/smist.c

Modified: trunk/sys/x86/acpica/OsdEnvironment.c
===================================================================
--- trunk/sys/x86/acpica/OsdEnvironment.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/acpica/OsdEnvironment.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -27,10 +27,11 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/acpica/OsdEnvironment.c 281687 2015-04-18 08:01:12Z jkim $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/acpica/OsdEnvironment.c 316303 2017-03-30 20:18:34Z jkim $");
 
 #include <sys/types.h>
 #include <sys/bus.h>
+#include <sys/kernel.h>
 #include <sys/sysctl.h>
 
 #include <contrib/dev/acpica/include/acpi.h>
@@ -61,6 +62,16 @@
 {
 	long acpi_root;
 
+	if (TUNABLE_ULONG_FETCH("acpi.rsdp", &acpi_root))
+		return (acpi_root);
+
+	/*
+	 * The hints mechanism is unreliable (it fails if anybody ever
+	 * compiled in hints to the kernel). It has been replaced
+	 * by the tunable method, but is used here as a fallback to
+	 * retain maximum compatibility between old loaders and new
+	 * kernels. It can be removed after 11.0R.
+	 */
 	if (resource_long_value("acpi", 0, "rsdp", &acpi_root) == 0)
 		return (acpi_root);
 

Modified: trunk/sys/x86/acpica/acpi_apm.c
===================================================================
--- trunk/sys/x86/acpica/acpi_apm.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/acpica/acpi_apm.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/acpica/acpi_apm.c 228283 2011-12-05 16:08:18Z ed $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/acpica/acpi_apm.c 228283 2011-12-05 16:08:18Z ed $");
 
 #include <sys/param.h>
 #include <sys/bus.h>

Modified: trunk/sys/x86/acpica/acpi_wakeup.c
===================================================================
--- trunk/sys/x86/acpica/acpi_wakeup.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/acpica/acpi_wakeup.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -29,10 +29,12 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/acpica/acpi_wakeup.c 331910 2018-04-03 07:52:06Z avg $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/acpica/acpi_wakeup.c 347700 2019-05-16 14:42:16Z markj $");
 
-#ifdef __i386__
-#include "opt_npx.h"
+#if defined(__amd64__)
+#define DEV_APIC
+#else
+#include "opt_apic.h"
 #endif
 
 #include <sys/param.h>
@@ -43,6 +45,7 @@
 #include <sys/memrange.h>
 #include <sys/smp.h>
 #include <sys/systm.h>
+#include <sys/cons.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -50,14 +53,17 @@
 #include <machine/clock.h>
 #include <machine/cpu.h>
 #include <machine/intr_machdep.h>
+#include <machine/md_var.h>
 #include <x86/mca.h>
 #include <machine/pcb.h>
-#include <machine/pmap.h>
 #include <machine/specialreg.h>
-#include <machine/md_var.h>
+#include <x86/ucode.h>
 
+#ifdef DEV_APIC
+#include <x86/apicreg.h>
+#include <x86/apicvar.h>
+#endif
 #ifdef SMP
-#include <x86/apicreg.h>
 #include <machine/smp.h>
 #include <machine/vmparam.h>
 #endif
@@ -74,6 +80,7 @@
 
 extern int		acpi_resume_beep;
 extern int		acpi_reset_video;
+extern int		acpi_susp_bounce;
 
 #ifdef SMP
 extern struct susppcb	**susppcbs;
@@ -82,7 +89,7 @@
 static struct susppcb	**susppcbs;
 #endif
 
-static void		*acpi_alloc_wakeup_handler(void);
+static void		*acpi_alloc_wakeup_handler(void **);
 static void		acpi_stop_beep(void *);
 
 #ifdef SMP
@@ -91,18 +98,14 @@
 #endif
 
 #ifdef __amd64__
-#define ACPI_PAGETABLES	3
+#define	ACPI_WAKEPAGES	4
 #else
-#define ACPI_PAGETABLES	0
+#define	ACPI_WAKEPAGES	1
 #endif
 
-#define	WAKECODE_VADDR(sc)				\
-    ((sc)->acpi_wakeaddr + (ACPI_PAGETABLES * PAGE_SIZE))
-#define	WAKECODE_PADDR(sc)				\
-    ((sc)->acpi_wakephys + (ACPI_PAGETABLES * PAGE_SIZE))
 #define	WAKECODE_FIXUP(offset, type, val)	do {	\
 	type	*addr;					\
-	addr = (type *)(WAKECODE_VADDR(sc) + offset);	\
+	addr = (type *)(sc->acpi_wakeaddr + (offset));	\
 	*addr = val;					\
 } while (0)
 
@@ -119,7 +122,7 @@
 acpi_wakeup_ap(struct acpi_softc *sc, int cpu)
 {
 	struct pcb *pcb;
-	int		vector = (WAKECODE_PADDR(sc) >> 12) & 0xff;
+	int		vector = (sc->acpi_wakephys >> 12) & 0xff;
 	int		apic_id = cpu_apic_ids[cpu];
 	int		ms;
 
@@ -162,7 +165,7 @@
 
 	/* setup a vector to our boot code */
 	*((volatile u_short *)WARMBOOT_OFF) = WARMBOOT_TARGET;
-	*((volatile u_short *)WARMBOOT_SEG) = WAKECODE_PADDR(sc) >> 4;
+	*((volatile u_short *)WARMBOOT_SEG) = sc->acpi_wakephys >> 4;
 	outb(CMOS_REG, BIOS_RESET);
 	outb(CMOS_DATA, BIOS_WARM);	/* 'warm-start' */
 
@@ -191,6 +194,10 @@
 {
 	ACPI_STATUS	status;
 	struct pcb	*pcb;
+#ifdef __amd64__
+	struct pcpu *pc;
+	int i;
+#endif
 
 	if (sc->acpi_wakeaddr == 0ul)
 		return (-1);	/* couldn't alloc wake memory */
@@ -203,7 +210,7 @@
 	if (acpi_resume_beep != 0)
 		timer_spkr_acquire();
 
-	AcpiSetFirmwareWakingVector(WAKECODE_PADDR(sc), 0);
+	AcpiSetFirmwareWakingVector(sc->acpi_wakephys, 0);
 
 	intr_suspend();
 
@@ -211,7 +218,7 @@
 	if (savectx(pcb)) {
 #ifdef __amd64__
 		fpususpend(susppcbs[0]->sp_fpususpend);
-#elif defined(DEV_NPX)
+#else
 		npxsuspend(susppcbs[0]->sp_fpususpend);
 #endif
 #ifdef SMP
@@ -220,11 +227,23 @@
 			return (0);	/* couldn't sleep */
 		}
 #endif
+#ifdef __amd64__
+		hw_ibrs_active = 0;
+		hw_ssb_active = 0;
+		cpu_stdext_feature3 = 0;
+		CPU_FOREACH(i) {
+			pc = pcpu_find(i);
+			pc->pc_ibpb_set = 0;
+		}
+#endif
 
 		WAKECODE_FIXUP(resume_beep, uint8_t, (acpi_resume_beep != 0));
 		WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0));
 
-#ifndef __amd64__
+#ifdef __amd64__
+		WAKECODE_FIXUP(wakeup_efer, uint64_t, rdmsr(MSR_EFER) &
+		    ~(EFER_LMA));
+#else
 		WAKECODE_FIXUP(wakeup_cr4, register_t, pcb->pcb_cr4);
 #endif
 		WAKECODE_FIXUP(wakeup_pcb, struct pcb *, pcb);
@@ -243,12 +262,21 @@
 			return (0);	/* couldn't sleep */
 		}
 
+		if (acpi_susp_bounce)
+			resumectx(pcb);
+
 		for (;;)
 			ia32_pause();
 	} else {
+		/*
+		 * Re-initialize console hardware as soon as possibe.
+		 * No console output (e.g. printf) is allowed before
+		 * this point.
+		 */
+		cnresume();
 #ifdef __amd64__
 		fpuresume(susppcbs[0]->sp_fpususpend);
-#elif defined(DEV_NPX)
+#else
 		npxresume(susppcbs[0]->sp_fpususpend);
 #endif
 	}
@@ -267,10 +295,14 @@
 	if (!intr_enabled) {
 		/* Wakeup MD procedures in interrupt disabled context */
 		if (sleep_result == 1) {
+			ucode_reload();
 			pmap_init_pat();
 			initializecpu();
 			PCPU_SET(switchtime, 0);
 			PCPU_SET(switchticks, ticks);
+#ifdef DEV_APIC
+			lapic_xapic_mode();
+#endif
 #ifdef SMP
 			if (!CPU_EMPTY(&suspcpus))
 				acpi_wakeup_cpus(sc);
@@ -300,11 +332,12 @@
 }
 
 static void *
-acpi_alloc_wakeup_handler(void)
+acpi_alloc_wakeup_handler(void *wakepages[ACPI_WAKEPAGES])
 {
-	void		*wakeaddr;
 	int		i;
 
+	memset(wakepages, 0, ACPI_WAKEPAGES * sizeof(*wakepages));
+
 	/*
 	 * Specify the region for our wakeup code.  We want it in the low 1 MB
 	 * region, excluding real mode IVT (0-0x3ff), BDA (0x400-0x4ff), EBDA
@@ -312,18 +345,18 @@
 	 * and ROM area (0xa0000 and above).  The temporary page tables must be
 	 * page-aligned.
 	 */
-	wakeaddr = contigmalloc((ACPI_PAGETABLES + 1) * PAGE_SIZE, M_DEVBUF,
-	    M_WAITOK, 0x500, 0xa0000, PAGE_SIZE, 0ul);
-	if (wakeaddr == NULL) {
-		printf("%s: can't alloc wake memory\n", __func__);
-		return (NULL);
+	for (i = 0; i < ACPI_WAKEPAGES; i++) {
+		wakepages[i] = contigmalloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT,
+		    0x500, 0xa0000, PAGE_SIZE, 0ul);
+		if (wakepages[i] == NULL) {
+			printf("%s: can't alloc wake memory\n", __func__);
+			goto freepages;
+		}
 	}
 	if (EVENTHANDLER_REGISTER(power_resume, acpi_stop_beep, NULL,
 	    EVENTHANDLER_PRI_LAST) == NULL) {
 		printf("%s: can't register event handler\n", __func__);
-		contigfree(wakeaddr, (ACPI_PAGETABLES + 1) * PAGE_SIZE,
-		    M_DEVBUF);
-		return (NULL);
+		goto freepages;
 	}
 	susppcbs = malloc(mp_ncpus * sizeof(*susppcbs), M_DEVBUF, M_WAITOK);
 	for (i = 0; i < mp_ncpus; i++) {
@@ -331,15 +364,23 @@
 		susppcbs[i]->sp_fpususpend = alloc_fpusave(M_WAITOK);
 	}
 
-	return (wakeaddr);
+	return (wakepages);
+
+freepages:
+	for (i = 0; i < ACPI_WAKEPAGES; i++)
+		if (wakepages[i] != NULL)
+			contigfree(wakepages[i], PAGE_SIZE, M_DEVBUF);
+	return (NULL);
 }
 
 void
 acpi_install_wakeup_handler(struct acpi_softc *sc)
 {
-	static void	*wakeaddr = NULL;
+	static void	*wakeaddr;
+	void		*wakepages[ACPI_WAKEPAGES];
 #ifdef __amd64__
 	uint64_t	*pt4, *pt3, *pt2;
+	vm_paddr_t	pt4pa, pt3pa, pt2pa;
 	int		i;
 #endif
 
@@ -346,24 +387,33 @@
 	if (wakeaddr != NULL)
 		return;
 
-	wakeaddr = acpi_alloc_wakeup_handler();
-	if (wakeaddr == NULL)
+	if (acpi_alloc_wakeup_handler(wakepages) == NULL)
 		return;
 
+	wakeaddr = wakepages[0];
 	sc->acpi_wakeaddr = (vm_offset_t)wakeaddr;
 	sc->acpi_wakephys = vtophys(wakeaddr);
 
-	bcopy(wakecode, (void *)WAKECODE_VADDR(sc), sizeof(wakecode));
+#ifdef __amd64__
+	pt4 = wakepages[1];
+	pt3 = wakepages[2];
+	pt2 = wakepages[3];
+	pt4pa = vtophys(pt4);
+	pt3pa = vtophys(pt3);
+	pt2pa = vtophys(pt2);
+#endif
 
+	bcopy(wakecode, (void *)sc->acpi_wakeaddr, sizeof(wakecode));
+
 	/* Patch GDT base address, ljmp targets. */
 	WAKECODE_FIXUP((bootgdtdesc + 2), uint32_t,
-	    WAKECODE_PADDR(sc) + bootgdt);
+	    sc->acpi_wakephys + bootgdt);
 	WAKECODE_FIXUP((wakeup_sw32 + 2), uint32_t,
-	    WAKECODE_PADDR(sc) + wakeup_32);
+	    sc->acpi_wakephys + wakeup_32);
 #ifdef __amd64__
 	WAKECODE_FIXUP((wakeup_sw64 + 1), uint32_t,
-	    WAKECODE_PADDR(sc) + wakeup_64);
-	WAKECODE_FIXUP(wakeup_pagetables, uint32_t, sc->acpi_wakephys);
+	    sc->acpi_wakephys + wakeup_64);
+	WAKECODE_FIXUP(wakeup_pagetables, uint32_t, pt4pa);
 #endif
 
 	/* Save pointers to some global data. */
@@ -375,12 +425,7 @@
 	WAKECODE_FIXUP(wakeup_cr3, register_t, vtophys(kernel_pmap->pm_pdir));
 #endif
 
-#else
-	/* Build temporary page tables below realmode code. */
-	pt4 = wakeaddr;
-	pt3 = pt4 + (PAGE_SIZE) / sizeof(uint64_t);
-	pt2 = pt3 + (PAGE_SIZE) / sizeof(uint64_t);
-
+#else /* __amd64__ */
 	/* Create the initial 1GB replicated page tables */
 	for (i = 0; i < 512; i++) {
 		/*
@@ -387,7 +432,7 @@
 		 * Each slot of the level 4 pages points
 		 * to the same level 3 page
 		 */
-		pt4[i] = (uint64_t)(sc->acpi_wakephys + PAGE_SIZE);
+		pt4[i] = (uint64_t)pt3pa;
 		pt4[i] |= PG_V | PG_RW | PG_U;
 
 		/*
@@ -394,7 +439,7 @@
 		 * Each slot of the level 3 pages points
 		 * to the same level 2 page
 		 */
-		pt3[i] = (uint64_t)(sc->acpi_wakephys + (2 * PAGE_SIZE));
+		pt3[i] = (uint64_t)pt2pa;
 		pt3[i] |= PG_V | PG_RW | PG_U;
 
 		/* The level 2 page slots are mapped with 2MB pages for 1GB. */
@@ -401,7 +446,7 @@
 		pt2[i] = i * (2 * 1024 * 1024);
 		pt2[i] |= PG_V | PG_RW | PG_PS | PG_U;
 	}
-#endif
+#endif /* !__amd64__ */
 
 	if (bootverbose)
 		device_printf(sc->acpi_dev, "wakeup code va %#jx pa %#jx\n",

Modified: trunk/sys/x86/acpica/madt.c
===================================================================
--- trunk/sys/x86/acpica/madt.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/acpica/madt.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -26,12 +26,13 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/acpica/madt.c 288461 2015-10-01 20:54:19Z jhb $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/acpica/madt.c 340016 2018-11-01 18:34:26Z jhb $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/malloc.h>
 #include <sys/smp.h>
 #include <vm/vm.h>
@@ -39,7 +40,9 @@
 
 #include <x86/apicreg.h>
 #include <machine/intr_machdep.h>
-#include <machine/apicvar.h>
+#include <x86/apicvar.h>
+#include <machine/md_var.h>
+#include <x86/vmware.h>
 
 #include <contrib/dev/acpica/include/acpi.h>
 #include <contrib/dev/acpica/include/aclocal.h>
@@ -59,7 +62,7 @@
 	u_int la_acpi_id;
 } lapics[MAX_APIC_ID + 1];
 
-static int madt_found_sci_override;
+int madt_found_sci_override;
 static ACPI_TABLE_MADT *madt;
 static vm_paddr_t madt_physaddr;
 static vm_offset_t madt_length;
@@ -104,7 +107,7 @@
 	madt_physaddr = acpi_find_table(ACPI_SIG_MADT);
 	if (madt_physaddr == 0)
 		return (ENXIO);
-	return (0);
+	return (-50);
 }
 
 /*
@@ -129,8 +132,86 @@
 static int
 madt_setup_local(void)
 {
+	ACPI_TABLE_DMAR *dmartbl;
+	vm_paddr_t dmartbl_physaddr;
+	const char *reason;
+	char *hw_vendor;
+	u_int p[4];
+	int user_x2apic;
+	bool bios_x2apic;
 
 	madt = pmap_mapbios(madt_physaddr, madt_length);
+	if ((cpu_feature2 & CPUID2_X2APIC) != 0) {
+		reason = NULL;
+
+		/*
+		 * Automatically detect several configurations where
+		 * x2APIC mode is known to cause troubles.  User can
+		 * override the setting with hw.x2apic_enable tunable.
+		 */
+		dmartbl_physaddr = acpi_find_table(ACPI_SIG_DMAR);
+		if (dmartbl_physaddr != 0) {
+			dmartbl = acpi_map_table(dmartbl_physaddr,
+			    ACPI_SIG_DMAR);
+			if ((dmartbl->Flags & ACPI_DMAR_X2APIC_OPT_OUT) != 0)
+				reason = "by DMAR table";
+			acpi_unmap_table(dmartbl);
+		}
+		if (vm_guest == VM_GUEST_VMWARE) {
+			vmware_hvcall(VMW_HVCMD_GETVCPU_INFO, p);
+			if ((p[0] & VMW_VCPUINFO_VCPU_RESERVED) != 0 ||
+			    (p[0] & VMW_VCPUINFO_LEGACY_X2APIC) == 0)
+				reason =
+				    "inside VMWare without intr redirection";
+		} else if (vm_guest == VM_GUEST_XEN) {
+			reason = "due to running under XEN";
+		} else if (vm_guest == VM_GUEST_NO &&
+		    CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+		    CPUID_TO_MODEL(cpu_id) == 0x2a) {
+			hw_vendor = kern_getenv("smbios.planar.maker");
+			/*
+			 * It seems that some Lenovo and ASUS
+			 * SandyBridge-based notebook BIOSes have a
+			 * bug which prevents booting AP in x2APIC
+			 * mode.  Since the only way to detect mobile
+			 * CPU is to check northbridge pci id, which
+			 * cannot be done that early, disable x2APIC
+			 * for all Lenovo and ASUS SandyBridge
+			 * machines.
+			 */
+			if (hw_vendor != NULL) {
+				if (!strcmp(hw_vendor, "LENOVO") ||
+				    !strcmp(hw_vendor,
+				    "ASUSTeK Computer Inc.")) {
+					reason =
+				    "for a suspected SandyBridge BIOS bug";
+				}
+				freeenv(hw_vendor);
+			}
+		}
+		bios_x2apic = lapic_is_x2apic();
+		if (reason != NULL && bios_x2apic) {
+			if (bootverbose)
+				printf("x2APIC should be disabled %s but "
+				    "already enabled by BIOS; enabling.\n",
+				     reason);
+			reason = NULL;
+		}
+		if (reason == NULL)
+			x2apic_mode = 1;
+		else if (bootverbose)
+			printf("x2APIC available but disabled %s\n", reason);
+		user_x2apic = x2apic_mode;
+		TUNABLE_INT_FETCH("hw.x2apic_enable", &user_x2apic);
+		if (user_x2apic != x2apic_mode) {
+			if (bios_x2apic && !user_x2apic)
+				printf("x2APIC disabled by tunable and "
+				    "enabled by BIOS; ignoring tunable.");
+			else
+				x2apic_mode = user_x2apic;
+		}
+	}
+
 	lapic_init(madt->Address);
 	printf("ACPI APIC Table: <%.*s %.*s>\n",
 	    (int)sizeof(madt->Header.OemId), madt->Header.OemId,
@@ -290,10 +371,6 @@
 			    apic->Id);
 		if (ioapics[apic->Id].io_apic != NULL)
 			panic("%s: Double APIC ID %u", __func__, apic->Id);
-		if (apic->GlobalIrqBase >= FIRST_MSI_INT) {
-			printf("MADT: Ignoring bogus I/O APIC ID %u", apic->Id);
-			break;
-		}
 		ioapics[apic->Id].io_apic = ioapic_create(apic->Address,
 		    apic->Id, apic->GlobalIrqBase);
 		ioapics[apic->Id].io_vector = apic->GlobalIrqBase;
@@ -396,41 +473,27 @@
 	return (0);
 }
 
-/*
- * Parse an interrupt source override for an ISA interrupt.
- */
-static void
-madt_parse_interrupt_override(ACPI_MADT_INTERRUPT_OVERRIDE *intr)
+void
+madt_parse_interrupt_values(void *entry,
+    enum intr_trigger *trig, enum intr_polarity *pol)
 {
-	void *new_ioapic, *old_ioapic;
-	u_int new_pin, old_pin;
-	enum intr_trigger trig;
-	enum intr_polarity pol;
+	ACPI_MADT_INTERRUPT_OVERRIDE *intr;
 	char buf[64];
 
-	if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->SourceIrq == 0 &&
-	    intr->GlobalIrq == 2) {
-		if (bootverbose)
-			printf("MADT: Skipping timer override\n");
-		return;
-	}
+	intr = entry;
+
 	if (bootverbose)
 		printf("MADT: Interrupt override: source %u, irq %u\n",
 		    intr->SourceIrq, intr->GlobalIrq);
 	KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero"));
-	if (madt_find_interrupt(intr->GlobalIrq, &new_ioapic, &new_pin) != 0) {
-		printf("MADT: Could not find APIC for vector %u (IRQ %u)\n",
-		    intr->GlobalIrq, intr->SourceIrq);
-		return;
-	}
 
 	/*
 	 * Lookup the appropriate trigger and polarity modes for this
 	 * entry.
 	 */
-	trig = interrupt_trigger(intr->IntiFlags, intr->SourceIrq);
-	pol = interrupt_polarity(intr->IntiFlags, intr->SourceIrq);
-	
+	*trig = interrupt_trigger(intr->IntiFlags, intr->SourceIrq);
+	*pol = interrupt_polarity(intr->IntiFlags, intr->SourceIrq);
+
 	/*
 	 * If the SCI is identity mapped but has edge trigger and
 	 * active-hi polarity or the force_sci_lo tunable is set,
@@ -440,30 +503,57 @@
 		madt_found_sci_override = 1;
 		if (getenv_string("hw.acpi.sci.trigger", buf, sizeof(buf))) {
 			if (tolower(buf[0]) == 'e')
-				trig = INTR_TRIGGER_EDGE;
+				*trig = INTR_TRIGGER_EDGE;
 			else if (tolower(buf[0]) == 'l')
-				trig = INTR_TRIGGER_LEVEL;
+				*trig = INTR_TRIGGER_LEVEL;
 			else
 				panic(
 				"Invalid trigger %s: must be 'edge' or 'level'",
 				    buf);
 			printf("MADT: Forcing SCI to %s trigger\n",
-			    trig == INTR_TRIGGER_EDGE ? "edge" : "level");
+			    *trig == INTR_TRIGGER_EDGE ? "edge" : "level");
 		}
 		if (getenv_string("hw.acpi.sci.polarity", buf, sizeof(buf))) {
 			if (tolower(buf[0]) == 'h')
-				pol = INTR_POLARITY_HIGH;
+				*pol = INTR_POLARITY_HIGH;
 			else if (tolower(buf[0]) == 'l')
-				pol = INTR_POLARITY_LOW;
+				*pol = INTR_POLARITY_LOW;
 			else
 				panic(
 				"Invalid polarity %s: must be 'high' or 'low'",
 				    buf);
 			printf("MADT: Forcing SCI to active %s polarity\n",
-			    pol == INTR_POLARITY_HIGH ? "high" : "low");
+			    *pol == INTR_POLARITY_HIGH ? "high" : "low");
 		}
 	}
+}
 
+/*
+ * Parse an interrupt source override for an ISA interrupt.
+ */
+static void
+madt_parse_interrupt_override(ACPI_MADT_INTERRUPT_OVERRIDE *intr)
+{
+	void *new_ioapic, *old_ioapic;
+	u_int new_pin, old_pin;
+	enum intr_trigger trig;
+	enum intr_polarity pol;
+
+	if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->SourceIrq == 0 &&
+	    intr->GlobalIrq == 2) {
+		if (bootverbose)
+			printf("MADT: Skipping timer override\n");
+		return;
+	}
+
+	if (madt_find_interrupt(intr->GlobalIrq, &new_ioapic, &new_pin) != 0) {
+		printf("MADT: Could not find APIC for vector %u (IRQ %u)\n",
+		    intr->GlobalIrq, intr->SourceIrq);
+		return;
+	}
+
+	madt_parse_interrupt_values(intr, &trig, &pol);
+
 	/* Remap the IRQ if it is mapped to a different interrupt vector. */
 	if (intr->SourceIrq != intr->GlobalIrq) {
 		/*
@@ -510,7 +600,7 @@
 	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
 		ioapic_set_triggermode(ioapic, pin,
 		    interrupt_trigger(nmi->IntiFlags, 0));
-	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
+	if (!(nmi->IntiFlags & ACPI_MADT_POLARITY_CONFORMS))
 		ioapic_set_polarity(ioapic, pin,
 		    interrupt_polarity(nmi->IntiFlags, 0));
 }

Modified: trunk/sys/x86/acpica/srat.c
===================================================================
--- trunk/sys/x86/acpica/srat.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/acpica/srat.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -27,8 +27,10 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/acpica/srat.c 299485 2016-05-11 22:06:28Z vangyzen $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/acpica/srat.c 322996 2017-08-29 07:01:15Z mav $");
 
+#include "opt_vm.h"
+
 #include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
@@ -47,7 +49,7 @@
 #include <contrib/dev/acpica/include/actables.h>
 
 #include <machine/intr_machdep.h>
-#include <machine/apicvar.h>
+#include <x86/apicvar.h>
 
 #include <dev/acpica/acpivar.h>
 
@@ -64,11 +66,102 @@
 static ACPI_TABLE_SRAT *srat;
 static vm_paddr_t srat_physaddr;
 
-static int vm_domains[VM_PHYSSEG_MAX];
+static int domain_pxm[MAXMEMDOM];
+static int ndomain;
 
+static ACPI_TABLE_SLIT *slit;
+static vm_paddr_t slit_physaddr;
+static int vm_locality_table[MAXMEMDOM * MAXMEMDOM];
+
 static void	srat_walk_table(acpi_subtable_handler *handler, void *arg);
 
 /*
+ * SLIT parsing.
+ */
+
+static void
+slit_parse_table(ACPI_TABLE_SLIT *s)
+{
+	int i, j;
+	int i_domain, j_domain;
+	int offset = 0;
+	uint8_t e;
+
+	/*
+	 * This maps the SLIT data into the VM-domain centric view.
+	 * There may be sparse entries in the PXM namespace, so
+	 * remap them to a VM-domain ID and if it doesn't exist,
+	 * skip it.
+	 *
+	 * It should result in a packed 2d array of VM-domain
+	 * locality information entries.
+	 */
+
+	if (bootverbose)
+		printf("SLIT.Localities: %d\n", (int) s->LocalityCount);
+	for (i = 0; i < s->LocalityCount; i++) {
+		i_domain = acpi_map_pxm_to_vm_domainid(i);
+		if (i_domain < 0)
+			continue;
+
+		if (bootverbose)
+			printf("%d: ", i);
+		for (j = 0; j < s->LocalityCount; j++) {
+			j_domain = acpi_map_pxm_to_vm_domainid(j);
+			if (j_domain < 0)
+				continue;
+			e = s->Entry[i * s->LocalityCount + j];
+			if (bootverbose)
+				printf("%d ", (int) e);
+			/* 255 == "no locality information" */
+			if (e == 255)
+				vm_locality_table[offset] = -1;
+			else
+				vm_locality_table[offset] = e;
+			offset++;
+		}
+		if (bootverbose)
+			printf("\n");
+	}
+}
+
+/*
+ * Look for an ACPI System Locality Distance Information Table ("SLIT")
+ */
+static int
+parse_slit(void)
+{
+
+	if (resource_disabled("slit", 0)) {
+		return (-1);
+	}
+
+	slit_physaddr = acpi_find_table(ACPI_SIG_SLIT);
+	if (slit_physaddr == 0) {
+		return (-1);
+	}
+
+	/*
+	 * Make a pass over the table to populate the cpus[] and
+	 * mem_info[] tables.
+	 */
+	slit = acpi_map_table(slit_physaddr, ACPI_SIG_SLIT);
+	slit_parse_table(slit);
+	acpi_unmap_table(slit);
+	slit = NULL;
+
+#ifdef VM_NUMA_ALLOC
+	/* Tell the VM about it! */
+	mem_locality = vm_locality_table;
+#endif
+	return (0);
+}
+
+/*
+ * SRAT parsing.
+ */
+
+/*
  * Returns true if a memory range overlaps with at least one range in
  * phys_avail[].
  */
@@ -78,7 +171,7 @@
 	int i;
 
 	for (i = 0; phys_avail[i] != 0 && phys_avail[i + 1] != 0; i += 2) {
-		if (phys_avail[i + 1] < start)
+		if (phys_avail[i + 1] <= start)
 			continue;
 		if (phys_avail[i] < end)
 			return (1);
@@ -110,6 +203,12 @@
 			    "enabled" : "disabled");
 		if (!(cpu->Flags & ACPI_SRAT_CPU_ENABLED))
 			break;
+		if (cpu->ApicId > MAX_APIC_ID) {
+			printf("SRAT: Ignoring local APIC ID %u (too high)\n",
+			    cpu->ApicId);
+			break;
+		}
+
 		if (cpus[cpu->ApicId].enabled) {
 			printf("SRAT: Duplicate local APIC ID %u\n",
 			    cpu->ApicId);
@@ -128,6 +227,12 @@
 			    "enabled" : "disabled");
 		if (!(x2apic->Flags & ACPI_SRAT_CPU_ENABLED))
 			break;
+		if (x2apic->ApicId > MAX_APIC_ID) {
+			printf("SRAT: Ignoring local APIC ID %u (too high)\n",
+			    x2apic->ApicId);
+			break;
+		}
+
 		KASSERT(!cpus[x2apic->ApicId].enabled,
 		    ("Duplicate local APIC ID %u", x2apic->ApicId));
 		cpus[x2apic->ApicId].domain = x2apic->ProximityDomain;
@@ -137,7 +242,7 @@
 		mem = (ACPI_SRAT_MEM_AFFINITY *)entry;
 		if (bootverbose)
 			printf(
-		    "SRAT: Found memory domain %d addr %jx len %jx: %s\n",
+		    "SRAT: Found memory domain %d addr 0x%jx len 0x%jx: %s\n",
 			    mem->ProximityDomain, (uintmax_t)mem->BaseAddress,
 			    (uintmax_t)mem->Length,
 			    (mem->Flags & ACPI_SRAT_MEM_ENABLED) ?
@@ -146,7 +251,7 @@
 			break;
 		if (!overlaps_phys_avail(mem->BaseAddress,
 		    mem->BaseAddress + mem->Length)) {
-			printf("SRAT: Ignoring memory at addr %jx\n",
+			printf("SRAT: Ignoring memory at addr 0x%jx\n",
 			    (uintmax_t)mem->BaseAddress);
 			break;
 		}
@@ -243,7 +348,7 @@
 				address = mem_info[i].end + 1;
 		}
 	}
-	printf("SRAT: No memory region found for %jx - %jx\n",
+	printf("SRAT: No memory region found for 0x%jx - 0x%jx\n",
 	    (uintmax_t)phys_avail[j], (uintmax_t)phys_avail[j + 1]);
 	return (ENXIO);
 }
@@ -258,48 +363,47 @@
 	int i, j, slot;
 
 	/* Enumerate all the domains. */
-	vm_ndomains = 0;
+	ndomain = 0;
 	for (i = 0; i < num_mem; i++) {
 		/* See if this domain is already known. */
-		for (j = 0; j < vm_ndomains; j++) {
-			if (vm_domains[j] >= mem_info[i].domain)
+		for (j = 0; j < ndomain; j++) {
+			if (domain_pxm[j] >= mem_info[i].domain)
 				break;
 		}
-		if (j < vm_ndomains && vm_domains[j] == mem_info[i].domain)
+		if (j < ndomain && domain_pxm[j] == mem_info[i].domain)
 			continue;
 
-		/* Insert the new domain at slot 'j'. */
-		slot = j;
-		for (j = vm_ndomains; j > slot; j--)
-			vm_domains[j] = vm_domains[j - 1];
-		vm_domains[slot] = mem_info[i].domain;
-		vm_ndomains++;
-		if (vm_ndomains > MAXMEMDOM) {
-			vm_ndomains = 1;
+		if (ndomain >= MAXMEMDOM) {
+			ndomain = 1;
 			printf("SRAT: Too many memory domains\n");
 			return (EFBIG);
 		}
+
+		/* Insert the new domain at slot 'j'. */
+		slot = j;
+		for (j = ndomain; j > slot; j--)
+			domain_pxm[j] = domain_pxm[j - 1];
+		domain_pxm[slot] = mem_info[i].domain;
+		ndomain++;
 	}
 
-	/* Renumber each domain to its index in the sorted 'domains' list. */
-	for (i = 0; i < vm_ndomains; i++) {
+	/* Renumber each domain to its index in the sorted 'domain_pxm' list. */
+	for (i = 0; i < ndomain; i++) {
 		/*
 		 * If the domain is already the right value, no need
 		 * to renumber.
 		 */
-		if (vm_domains[i] == i)
+		if (domain_pxm[i] == i)
 			continue;
 
 		/* Walk the cpu[] and mem_info[] arrays to renumber. */
 		for (j = 0; j < num_mem; j++)
-			if (mem_info[j].domain == vm_domains[i])
+			if (mem_info[j].domain == domain_pxm[i])
 				mem_info[j].domain = i;
 		for (j = 0; j <= MAX_APIC_ID; j++)
-			if (cpus[j].enabled && cpus[j].domain == vm_domains[i])
+			if (cpus[j].enabled && cpus[j].domain == domain_pxm[i])
 				cpus[j].domain = i;
 	}
-	KASSERT(vm_ndomains > 0,
-	    ("renumber_domains: invalid final vm_ndomains setup"));
 
 	return (0);
 }
@@ -307,17 +411,17 @@
 /*
  * Look for an ACPI System Resource Affinity Table ("SRAT")
  */
-static void
-parse_srat(void *dummy)
+static int
+parse_srat(void)
 {
 	int error;
 
 	if (resource_disabled("srat", 0))
-		return;
+		return (-1);
 
 	srat_physaddr = acpi_find_table(ACPI_SIG_SRAT);
 	if (srat_physaddr == 0)
-		return;
+		return (-1);
 
 	/*
 	 * Make a pass over the table to populate the cpus[] and
@@ -331,15 +435,44 @@
 	if (error || check_domains() != 0 || check_phys_avail() != 0 ||
 	    renumber_domains() != 0) {
 		srat_physaddr = 0;
-		return;
+		return (-1);
 	}
 
+#ifdef VM_NUMA_ALLOC
 	/* Point vm_phys at our memory affinity table. */
+	vm_ndomains = ndomain;
 	mem_affinity = mem_info;
+#endif
+
+	return (0);
 }
-SYSINIT(parse_srat, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_srat, NULL);
 
 static void
+init_mem_locality(void)
+{
+	int i;
+
+	/*
+	 * For now, assume -1 == "no locality information for
+	 * this pairing.
+	 */
+	for (i = 0; i < MAXMEMDOM * MAXMEMDOM; i++)
+		vm_locality_table[i] = -1;
+}
+
+static void
+parse_acpi_tables(void *dummy)
+{
+
+	if (parse_srat() < 0)
+		return;
+	init_mem_locality();
+	(void) parse_slit();
+}
+SYSINIT(parse_acpi_tables, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_acpi_tables,
+    NULL);
+
+static void
 srat_walk_table(acpi_subtable_handler *handler, void *arg)
 {
 
@@ -348,7 +481,7 @@
 }
 
 /*
- * Setup per-CPU ACPI IDs.
+ * Setup per-CPU domain IDs.
  */
 static void
 srat_set_cpus(void *dummy)
@@ -369,6 +502,7 @@
 			panic("SRAT: CPU with APIC ID %u is not known",
 			    pc->pc_apic_id);
 		pc->pc_domain = cpu->domain;
+		CPU_SET(i, &cpuset_domain[cpu->domain]);
 		if (bootverbose)
 			printf("SRAT: CPU %u has memory domain %d\n", i,
 			    cpu->domain);
@@ -386,8 +520,8 @@
 {
 	int i;
 
-	for (i = 0; i < vm_ndomains; i++) {
-		if (vm_domains[i] == pxm)
+	for (i = 0; i < ndomain; i++) {
+		if (domain_pxm[i] == pxm)
 			return (i);
 	}
 
@@ -394,4 +528,13 @@
 	return (-1);
 }
 
+#else /* MAXMEMDOM == 1 */
+
+int
+acpi_map_pxm_to_vm_domainid(int pxm)
+{
+
+	return (-1);
+}
+
 #endif /* MAXMEMDOM > 1 */

Modified: trunk/sys/x86/bios/smbios.c
===================================================================
--- trunk/sys/x86/bios/smbios.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/bios/smbios.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/bios/smbios.c 241073 2012-09-30 15:42:20Z kevlo $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/bios/smbios.c 241073 2012-09-30 15:42:20Z kevlo $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/x86/bios/vpd.c
===================================================================
--- trunk/sys/x86/bios/vpd.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/bios/vpd.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/bios/vpd.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/bios/vpd.c 227309 2011-11-07 15:43:11Z ed $");
 
 /*
  * VPD decoder for IBM systems (Thinkpads)

Modified: trunk/sys/x86/cpufreq/est.c
===================================================================
--- trunk/sys/x86/cpufreq/est.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/cpufreq/est.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/cpufreq/est.c 260473 2014-01-09 10:44:27Z mav $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/cpufreq/est.c 259197 2013-12-10 20:25:43Z mav $");
 
 #include <sys/param.h>
 #include <sys/bus.h>

Modified: trunk/sys/x86/cpufreq/hwpstate.c
===================================================================
--- trunk/sys/x86/cpufreq/hwpstate.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/cpufreq/hwpstate.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -45,7 +45,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/cpufreq/hwpstate.c 326638 2017-12-06 21:40:24Z jkim $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/cpufreq/hwpstate.c 326637 2017-12-06 21:39:01Z jkim $");
 
 #include <sys/param.h>
 #include <sys/bus.h>

Modified: trunk/sys/x86/cpufreq/p4tcc.c
===================================================================
--- trunk/sys/x86/cpufreq/p4tcc.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/cpufreq/p4tcc.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/cpufreq/p4tcc.c 250487 2013-05-10 22:43:27Z hiren $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/cpufreq/p4tcc.c 250487 2013-05-10 22:43:27Z hiren $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/x86/cpufreq/powernow.c
===================================================================
--- trunk/sys/x86/cpufreq/powernow.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/cpufreq/powernow.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/cpufreq/powernow.c 305615 2016-09-08 15:06:28Z pfg $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/cpufreq/powernow.c 305614 2016-09-08 15:05:25Z pfg $");
 
 #include <sys/param.h>
 #include <sys/bus.h>

Modified: trunk/sys/x86/cpufreq/smist.c
===================================================================
--- trunk/sys/x86/cpufreq/smist.c	2020-02-08 19:33:27 UTC (rev 12311)
+++ trunk/sys/x86/cpufreq/smist.c	2020-02-08 19:34:34 UTC (rev 12312)
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/x86/cpufreq/smist.c 187597 2009-01-22 20:29:07Z jkim $");
+__FBSDID("$FreeBSD: stable/11/sys/x86/cpufreq/smist.c 297793 2016-04-10 23:07:00Z pfg $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -224,7 +224,7 @@
 		bus_dma_tag_destroy(tag);
 		device_printf(dev, "can't load mem\n");
 		return (ENXIO);
-	};
+	}
 	DPRINT(dev, "taking ownership over BIOS return %d\n", cb_data.result);
 	bus_dmamap_unload(tag, map);
 	bus_dmamem_free(tag, cb_data.buf, map);



More information about the Midnightbsd-cvs mailing list