Hi,

Here is a work-in-progress driver for the Intel eXtreme Tuning Utility.
The main purpose is to add more sensors to the existing pool.

I am very interested in tests on recent Intel K- and X-series processors!
None the less, please test on all Intel cpus and if you see acpixtu
attaching please send me a private mail with the dmesg and acpidump.


I initially implemented it for the x260, but there is a mysterious XTUS
AML external method that seems to be blocking it on my machine. I tried
overwritting it with hacks in dsdt.c but failed.

After seeing a few more acpidumps (that don't have the blocking XTUS
method) I decided to send it here for wider tests.


Thank you,
Paul


Index: arch/amd64/amd64/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/locore.S,v
retrieving revision 1.82
diff -u -p -u -p -r1.82 locore.S
--- arch/amd64/amd64/locore.S   16 Jul 2016 06:04:29 -0000      1.82
+++ arch/amd64/amd64/locore.S   2 Sep 2016 15:05:06 -0000
@@ -1202,3 +1202,18 @@ _C_LABEL(xen_hypercall_page):
 _C_LABEL(hv_hypercall_page):
        .skip   0x1000, 0xcc
 #endif /* NXEN > 0 */
+
+/* acpixtu_smi_read(sc->sc_fadt->smi_cmd, xtu_port, &settings_addr) */
+ENTRY(acpixtu_smi_read)
+       /* Read BIOS Settings Command */
+       xorl    %ecx,%ecx
+       /* 32-bit Physical Memory Data Location */
+       movl    %edx, %ebx
+       /* Write the SW SMI Command Value to the SW SMI Port */
+       movq    %rdi, %rdx
+       movq    %rsi, %rax
+       outb    %al, %dx
+       /* Return Value in EBX */
+       xorq    %rax, %rax
+       movl    %ebx, %eax
+       ret
Index: arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.430
diff -u -p -u -p -r1.430 GENERIC
--- arch/amd64/conf/GENERIC     1 Sep 2016 10:04:51 -0000       1.430
+++ arch/amd64/conf/GENERIC     2 Sep 2016 15:05:07 -0000
@@ -67,6 +67,7 @@ sdhc*         at acpi?
 acpicbkbd*     at acpi?
 acpials*       at acpi?
 tpm*           at acpi?
+acpixtu*       at acpi?
 
 mpbios0                at bios0
 
Index: dev/acpi/acpireg.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpireg.h,v
retrieving revision 1.36
diff -u -p -u -p -r1.36 acpireg.h
--- dev/acpi/acpireg.h  10 Jul 2016 20:36:41 -0000      1.36
+++ dev/acpi/acpireg.h  2 Sep 2016 15:05:07 -0000
@@ -778,4 +778,7 @@ struct acpi_ivrs {
 #define ACPI_DEV_DWIIC4        "INT3433"
 #define ACPI_DEV_DWIIC5        "80860F41"
 
+/* Intel Extreme Tuning Utility */
+#define ACPI_DEV_XTU "INT3394"
+
 #endif /* !_DEV_ACPI_ACPIREG_H_ */
Index: dev/acpi/acpixtu.c
===================================================================
RCS file: dev/acpi/acpixtu.c
diff -N dev/acpi/acpixtu.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dev/acpi/acpixtu.c  2 Sep 2016 15:05:07 -0000
@@ -0,0 +1,252 @@
+/*     $OpenBSD$       */
+/*
+ * Copyright (c) 2016 Paul Irofti <piro...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/types.h>
+#include <sys/pool.h>
+
+#include <machine/bus.h>
+
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpidev.h>
+#include <dev/acpi/amltypes.h>
+#include <dev/acpi/dsdt.h>
+
+struct acpixtu_softc {
+       struct device sc_dev;
+
+       struct acpi_softc *sc_acpi;
+       struct aml_node *sc_devnode;
+
+       int sc_tsdd;
+       int sc_vsdd;
+       int sc_fsdd;
+};
+
+int    acpixtu_match(struct device *, void *, void *);
+void   acpixtu_attach(struct device *, struct device *, void *);
+int    acpixtu_notify(struct aml_node *, int, void *);
+
+struct cfattach acpixtu_ca = {
+       sizeof(struct acpixtu_softc), acpixtu_match, acpixtu_attach
+};
+
+struct cfdriver acpixtu_cd = {
+       NULL, "acpixtu", DV_DULL
+};
+
+static const char *acpixtu_hids[] = { ACPI_DEV_XTU, 0 };
+uint32_t acpixtu_smi_read(int, int, uint8_t *);
+
+static int
+acpixtu_get_data(struct acpixtu_softc *sc, char *method)
+{
+       struct aml_value res;
+       int i;
+
+       if (aml_evalname(sc->sc_acpi, sc->sc_devnode, method, 0, NULL, &res)) {
+               printf("%s: %s method is absent\n", DEVNAME(sc), method);
+               return 1;
+       }
+       printf("%s: %s(%s) AML dump\n", DEVNAME(sc), __func__, method);
+       aml_showvalue(&res);
+       if (res.type == AML_OBJTYPE_INTEGER && !aml_val2int(&res)) {
+               printf("%s: %s got null package\n", DEVNAME(sc), method);
+               aml_freevalue(&res);
+               return 1;
+       } else if (res.type != AML_OBJTYPE_PACKAGE) {
+               aml_freevalue(&res);
+               return 1;
+       }
+       printf("%s: %s(%s) sensor data\n", DEVNAME(sc), __func__, method);
+       for (i = 0; i < res.length; i += 4) {
+               int usage, id, value;
+               usage = aml_val2int(res.v_package[i]);
+               id = aml_val2int(res.v_package[i + 1]);
+               value = aml_val2int(res.v_package[i + 2]);
+               value = value - 2732;
+               printf("sensor[%d]: %d %d %d\n", i/4, usage, id, value);
+       }
+       aml_freevalue(&res);
+       return 0;
+}
+
+int
+acpixtu_match(struct device *parent, void *match, void *aux)
+{
+       struct acpi_attach_args *aaa = aux;
+       struct cfdata *cf = match;
+
+       return acpi_matchhids(aaa, acpixtu_hids, cf->cf_driver->cd_name);
+}
+
+void
+acpixtu_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct acpixtu_softc *sc = (struct acpixtu_softc *)self;
+       struct acpi_attach_args *aaa = aux;
+
+       struct aml_value args, res;
+       int64_t version, major, minor, sampling;
+       int i, xtu_port;
+       uint32_t rc;
+
+#define ACPIXTU_INFO_SIZE      0x20
+       uint8_t *info, *preinfo;
+       uint32_t info_length = ACPIXTU_INFO_SIZE;
+       uint16_t info_major = 2;
+       uint16_t info_minor = 0;
+
+       sc->sc_acpi = (struct acpi_softc *)parent;
+       sc->sc_devnode = aaa->aaa_node;
+
+       if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "IVER", 0, NULL, &res))
+               return;
+       if (res.type != AML_OBJTYPE_INTEGER)
+               return;
+       version = aml_val2int(&res);
+       major = version >> 16;
+       minor = version & 0x0000ffff;
+
+       printf(": %s ver%lld.%lld", sc->sc_devnode->name, major, minor);
+
+       if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "GACI", 0, NULL, &res))
+               return;
+       if (res.type == AML_OBJTYPE_PACKAGE) {
+               if (aml_val2int(res.v_package[0]) != 0) {
+                       printf(" GACI failed (%lld)",
+                           aml_val2int(res.v_package[0]));
+                       return;
+               }
+               if (res.v_package[1]->type == AML_OBJTYPE_INTEGER &&
+                   aml_val2int(res.v_package[1]) == 0)
+                       printf(" monitor-only");
+       }
+       aml_freevalue(&res);
+       printf("\n");
+
+       /* Enable sensors */
+       sc->sc_tsdd = sc->sc_vsdd = sc->sc_fsdd = 1;
+
+       /* Fetch XMP Profiles */
+       memset(&args, 0, sizeof(args));
+
+       args.v_integer = 1;
+       args.type = AML_OBJTYPE_INTEGER;
+       aml_evalname(sc->sc_acpi, sc->sc_devnode, "GXDV", 1, &args, &res);
+       printf("GXDV 1:\n");
+       aml_showvalue(&res);
+       aml_freevalue(&res);
+
+       args.v_integer = 2;
+       aml_evalname(sc->sc_acpi, sc->sc_devnode, "GXDV", 1, &args, &res);
+       printf("GXDV 2:\n");
+       aml_showvalue(&res);
+       aml_freevalue(&res);
+
+       /* Fetch SMI Command Value */
+       aml_evalname(sc->sc_acpi, sc->sc_devnode, "GSCV", 0, NULL, &res);
+       if (res.type == AML_OBJTYPE_PACKAGE) {
+               for (i = 0; i < res.length; i++) {
+                       xtu_port = aml_val2int(res.v_package[i]);
+                       printf("%s: SMI (type %d) cmd %d\n", DEVNAME(sc),
+                           res.v_package[i]->type, xtu_port);
+               }
+       } else if (res.type == AML_OBJTYPE_INTEGER) {
+               xtu_port = aml_val2int(&res);
+               printf("%s: SMI (type %d) cmd %d\n", DEVNAME(sc),
+                   res.type, xtu_port);
+       } else
+               printf("%s: SMI unhandled type %d\n", DEVNAME(sc), res.type);
+       aml_freevalue(&res);
+
+       /*
+        * Issue an SMI Read to collect current BIOS state
+        */
+       preinfo = info = dma_alloc(ACPIXTU_INFO_SIZE, PR_WAITOK | PR_ZERO);
+       memcpy(&info[0], "$BD2", 4);                            /* Signature */
+       memcpy(&info[4], &info_length, sizeof(info_length));    /* Length */
+       memcpy(&info[8], &info_major, sizeof(info_major));      /* Ver. Major */
+       memcpy(&info[10], &info_minor, sizeof(info_minor));     /* Ver. Minor */
+       printf("%s: info ptr %p ", DEVNAME(sc), info);
+       for (i = 0; i < ACPIXTU_INFO_SIZE; i++)
+               printf("0x%x ", info[i]);
+       printf("\n");
+
+       printf("%s: smi_read(%d, %d, %p)\n", DEVNAME(sc),
+           sc->sc_acpi->sc_fadt->smi_cmd, xtu_port, info);
+       rc = acpixtu_smi_read(sc->sc_acpi->sc_fadt->smi_cmd, xtu_port, info);
+
+       printf("%s: info ptr %p ret %X ", DEVNAME(sc), info, rc);
+       if (preinfo != info)
+               return;
+       memcpy(&info_length, &info[0], 4);
+       printf("result %X", info_length);
+       memcpy(&info_length, &info[4], 4);
+       printf(" len %X", info_length);
+       memcpy(&info_major, &info[8], sizeof(info_major));      /* Ver. Major */
+       memcpy(&info_minor, &info[10], sizeof(info_minor));     /* Ver. Minor */
+       printf(" version %d.%d ", info_major, info_minor);
+       memcpy(&info_length, &info[0xc], 4);
+       printf(" settings %d ", info_length);
+       printf("\n");
+
+       /* Sensor Sampling Period */
+       aml_evalname(sc->sc_acpi, sc->sc_devnode, "SDSP", 0, NULL, &res);
+       if (res.type == AML_OBJTYPE_INTEGER) {
+               sampling = aml_val2int(&res);
+               printf("%s: Sampling %lld00ms\n", DEVNAME(sc), sampling);
+       } else
+               printf("%s: Sampling unhandled type %d\n",
+                   DEVNAME(sc), res.type);
+       aml_freevalue(&res);
+
+       /*
+        * XXX: Wait for sensor data to be available.
+        * Ideally this would be a poll argument.
+        */
+       if (sampling)
+               delay(sampling * 10 * 1000);
+
+       aml_register_notify(sc->sc_devnode, aaa->aaa_dev,
+           acpixtu_notify, sc, ACPIDEV_POLL);
+
+       dma_free(info, ACPIXTU_INFO_SIZE);
+}
+
+int
+acpixtu_notify(struct aml_node *node, int notify, void *arg)
+{
+       struct acpixtu_softc *sc = arg;
+
+       if (sc->sc_tsdd && acpixtu_get_data(sc, "TSDD")) {
+               printf("%s: disabling TSDD\n", DEVNAME(sc));
+               sc->sc_tsdd = 0;
+       }
+       if (sc->sc_vsdd && acpixtu_get_data(sc, "VSDD")) {
+               printf("%s: disabling VSDD\n", DEVNAME(sc));
+               sc->sc_vsdd = 0;
+       }
+       if (sc->sc_fsdd && acpixtu_get_data(sc, "FSDD")) {
+               printf("%s: disabling FSDD\n", DEVNAME(sc));
+               sc->sc_fsdd = 0;
+       }
+
+       return 0;
+}
Index: dev/acpi/files.acpi
===================================================================
RCS file: /cvs/src/sys/dev/acpi/files.acpi,v
retrieving revision 1.35
diff -u -p -u -p -r1.35 files.acpi
--- dev/acpi/files.acpi 3 Aug 2016 17:23:38 -0000       1.35
+++ dev/acpi/files.acpi 2 Sep 2016 15:05:07 -0000
@@ -145,3 +145,8 @@ file        dev/acpi/acpials.c              acpials
 device tpm
 attach tpm at acpi
 file   dev/acpi/tpm.c                  tpm
+
+# Intel Extreme Tuning Utility
+device acpixtu
+attach acpixtu at acpi
+file   dev/acpi/acpixtu.c              acpixtu

Reply via email to