svn commit: r274001 - in stable/10: include sys/dev/acpica

Rui Paulo rpaulo at FreeBSD.org
Mon Nov 3 03:18:00 UTC 2014


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++) {


More information about the svn-src-stable-10 mailing list