Author: rpaulo
Date: Mon Nov  3 03:17:58 2014
New Revision: 274001
URL: https://svnweb.freebsd.org/changeset/base/274001

Log:
  MFC 273598 273602 273607 273613 273647:
  
      Userland HPET support.

Modified:
  stable/10/include/Makefile
  stable/10/sys/dev/acpica/acpi_hpet.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/include/Makefile
==============================================================================
--- stable/10/include/Makefile  Mon Nov  3 03:12:15 2014        (r274000)
+++ stable/10/include/Makefile  Mon Nov  3 03:17:58 2014        (r274001)
@@ -164,6 +164,8 @@ copies:
 .endfor
        cd ${.CURDIR}/../sys/dev/acpica; \
        ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 acpiio.h \
+           ${DESTDIR}${INCLUDEDIR}/dev/acpica; \
+       ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 acpi_hpet.h \
            ${DESTDIR}${INCLUDEDIR}/dev/acpica
        cd ${.CURDIR}/../sys/dev/agp; \
        ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 agpreg.h \
@@ -246,7 +248,7 @@ symlinks:
        done
 .endfor
        cd ${.CURDIR}/../sys/dev/acpica; \
-       for h in acpiio.h; do \
+       for h in acpiio.h acpi_hpet.h; do \
                ln -fs ../../../../sys/dev/acpica/$$h \
                    ${DESTDIR}${INCLUDEDIR}/dev/acpica; \
        done

Modified: stable/10/sys/dev/acpica/acpi_hpet.c
==============================================================================
--- stable/10/sys/dev/acpica/acpi_hpet.c        Mon Nov  3 03:12:15 2014        
(r274000)
+++ stable/10/sys/dev/acpica/acpi_hpet.c        Mon Nov  3 03:17:58 2014        
(r274001)
@@ -35,11 +35,13 @@ __FBSDID("$FreeBSD$");
 #include "opt_apic.h"
 #endif
 #include <sys/param.h>
+#include <sys/conf.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/proc.h>
 #include <sys/rman.h>
+#include <sys/mman.h>
 #include <sys/time.h>
 #include <sys/smp.h>
 #include <sys/sysctl.h>
@@ -106,6 +108,19 @@ struct hpet_softc {
                char                    name[8];
        }                       t[32];
        int                     num_timers;
+       struct cdev             *pdev;
+       int                     mmap_allow;
+       int                     mmap_allow_write;
+};
+
+static d_open_t hpet_open;
+static d_mmap_t hpet_mmap;
+
+static struct cdevsw hpet_cdevsw = {
+       .d_version =    D_VERSION,
+       .d_name =       "hpet",
+       .d_open =       hpet_open,
+       .d_mmap =       hpet_mmap,
 };
 
 static u_int hpet_get_timecount(struct timecounter *tc);
@@ -314,8 +329,37 @@ hpet_find_irq_rid(device_t dev, u_long s
        }
 }
 
+static int
+hpet_open(struct cdev *cdev, int oflags, int devtype, struct thread *td)
+{
+       struct hpet_softc *sc;
+
+       sc = cdev->si_drv1;
+       if (!sc->mmap_allow)
+               return (EPERM);
+       else
+               return (0);
+}
+
+static int
+hpet_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr,
+    int nprot, vm_memattr_t *memattr)
+{
+       struct hpet_softc *sc;
+
+       sc = cdev->si_drv1;
+       if (offset > rman_get_size(sc->mem_res))
+               return (EINVAL);
+       if (!sc->mmap_allow_write && (nprot & PROT_WRITE))
+               return (EPERM);
+       *paddr = rman_get_start(sc->mem_res) + offset;
+       *memattr = VM_MEMATTR_UNCACHEABLE;
+
+       return (0);
+}
+
 /* Discover the HPET via the ACPI table of the same name. */
-static void 
+static void
 hpet_identify(driver_t *driver, device_t parent)
 {
        ACPI_TABLE_HPET *hpet;
@@ -646,8 +690,8 @@ hpet_attach(device_t dev)
 #ifdef DEV_APIC
                if ((t->caps & HPET_TCAP_FSB_INT_DEL) && t->irq >= 0) {
                        uint64_t addr;
-                       uint32_t data;  
-                       
+                       uint32_t data;
+
                        if (PCIB_MAP_MSI(
                            device_get_parent(device_get_parent(dev)), dev,
                            t->irq, &addr, &data) == 0) {
@@ -697,6 +741,31 @@ hpet_attach(device_t dev)
                        maxhpetet++;
                }
        }
+
+       sc->pdev = make_dev(&hpet_cdevsw, 0, UID_ROOT, GID_WHEEL,
+           0600, "hpet%d", device_get_unit(dev));
+       if (sc->pdev) {
+               sc->pdev->si_drv1 = sc;
+               sc->mmap_allow = 1;
+               TUNABLE_INT_FETCH("hw.acpi.hpet.mmap_allow",
+                   &sc->mmap_allow);
+               sc->mmap_allow_write = 1;
+               TUNABLE_INT_FETCH("hw.acpi.hpet.mmap_allow_write",
+                   &sc->mmap_allow_write);
+               SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+                   SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+                   OID_AUTO, "mmap_allow",
+                   CTLFLAG_RW, &sc->mmap_allow, 0,
+                   "Allow userland to memory map HPET");
+               SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+                   SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+                   OID_AUTO, "mmap_allow_write",
+                   CTLFLAG_RW, &sc->mmap_allow_write, 0,
+                   "Allow userland write to the HPET register space");
+       } else
+               device_printf(dev, "could not create /dev/hpet%d\n",
+                   device_get_unit(dev));
+
        return (0);
 }
 
@@ -741,8 +810,8 @@ hpet_resume(device_t dev)
 #ifdef DEV_APIC
                if (t->irq >= 0 && (sc->legacy_route == 0 || i >= 2)) {
                        uint64_t addr;
-                       uint32_t data;  
-                       
+                       uint32_t data;
+
                        if (PCIB_MAP_MSI(
                            device_get_parent(device_get_parent(dev)), dev,
                            t->irq, &addr, &data) == 0) {
@@ -813,7 +882,7 @@ hpet_remap_intr(device_t dev, device_t c
        struct hpet_softc *sc = device_get_softc(dev);
        struct hpet_timer *t;
        uint64_t addr;
-       uint32_t data;  
+       uint32_t data;
        int error, i;
 
        for (i = 0; i < sc->num_timers; i++) {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to