[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