From owner-svn-src-head@FreeBSD.ORG Fri Oct 24 19:06:05 2014 Return-Path: Delivered-To: svn-src-head@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D71D3349; Fri, 24 Oct 2014 19:06:05 +0000 (UTC) Received: from citadel.icyb.net.ua (citadel.icyb.net.ua [212.40.38.140]) by mx1.freebsd.org (Postfix) with ESMTP id 8A35DE78; Fri, 24 Oct 2014 19:06:03 +0000 (UTC) Received: from porto.starpoint.kiev.ua (porto-e.starpoint.kiev.ua [212.40.38.100]) by citadel.icyb.net.ua (8.8.8p3/ICyb-2.3exp) with ESMTP id WAA12100; Fri, 24 Oct 2014 22:06:01 +0300 (EEST) (envelope-from avg@FreeBSD.org) Received: from localhost ([127.0.0.1]) by porto.starpoint.kiev.ua with esmtp (Exim 4.34 (FreeBSD)) id 1XhkBU-0006Tv-UP; Fri, 24 Oct 2014 22:06:00 +0300 Message-ID: <544AA2E1.7000508@FreeBSD.org> Date: Fri, 24 Oct 2014 22:05:05 +0300 From: Andriy Gapon User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:31.0) Gecko/20100101 Thunderbird/31.1.2 MIME-Version: 1.0 To: Rui Paulo , src-committers@FreeBSD.org, svn-src-all@FreeBSD.org, svn-src-head@FreeBSD.org Subject: Re: svn commit: r273598 - in head: include sys/dev/acpica References: <201410241839.s9OIdG0E077139@svn.freebsd.org> In-Reply-To: <201410241839.s9OIdG0E077139@svn.freebsd.org> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Oct 2014 19:06:06 -0000 On 24/10/2014 21:39, Rui Paulo wrote: > Author: rpaulo > Date: Fri Oct 24 18:39:15 2014 > New Revision: 273598 > URL: https://svnweb.freebsd.org/changeset/base/273598 > > Log: > HPET: create /dev/hpetN as a way to access HPET from userland. > > In some cases, TSC is broken and special applications might benefit > from memory mapping HPET and reading the registers to count time. > Most often the main HPET counter is 32-bit only[1], so this only gives > the application a 300 second window based on the default HPET > interval. > Other applications, such as Intel's DPDK, expect /dev/hpet to be > present and use it to count time as well. Does this device attempt to play nice with eventtimer infrastructure that may use the same timer? > Although we have an almost userland version of gettimeofday() which > uses rdtsc in userland, it's not always possible to use it, depending > on how broken the multi-socket hardware is. > > Install the acpi_hpet.h so that applications can use the HPET register > definitions. > > [1] I haven't found a system where HPET's main counter uses more than > 32 bit. There seems to be a discrepancy in the Intel documentation > (claiming it's a 64-bit counter) and the actual implementation (a > 32-bit counter in a 64-bit memory area). > > MFC after: 1 week > Relnotes: yes > > Modified: > head/include/Makefile > head/sys/dev/acpica/acpi_hpet.c > > Modified: head/include/Makefile > ============================================================================== > --- head/include/Makefile Fri Oct 24 17:40:32 2014 (r273597) > +++ head/include/Makefile Fri Oct 24 18:39:15 2014 (r273598) > @@ -159,6 +159,8 @@ copies: > 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 \ > ${DESTDIR}${INCLUDEDIR}/dev/agp > @@ -243,7 +245,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: head/sys/dev/acpica/acpi_hpet.c > ============================================================================== > --- head/sys/dev/acpica/acpi_hpet.c Fri Oct 24 17:40:32 2014 (r273597) > +++ head/sys/dev/acpica/acpi_hpet.c Fri Oct 24 18:39:15 2014 (r273598) > @@ -35,11 +35,13 @@ __FBSDID("$FreeBSD$"); > #include "opt_apic.h" > #endif > #include > +#include > #include > #include > #include > #include > #include > +#include > #include > #include > #include > @@ -106,6 +108,23 @@ struct hpet_softc { > char name[8]; > } t[32]; > int num_timers; > + struct cdev *pdev; > + int mmap_allow; > + int mmap_allow_write; > + int devinuse; > +}; > + > +static d_open_t hpet_open; > +static d_close_t hpet_close; > +static d_mmap_t hpet_mmap; > + > +static struct cdevsw hpet_cdevsw = { > + .d_version = D_VERSION, > + .d_flags = D_TRACKCLOSE, > + .d_name = "hpet", > + .d_open = hpet_open, > + .d_close = hpet_close, > + .d_mmap = hpet_mmap, > }; > > static u_int hpet_get_timecount(struct timecounter *tc); > @@ -317,6 +336,47 @@ 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); > + if (atomic_cmpset_32(&sc->devinuse, 0, 1) == 0) > + return (EBUSY); > + else > + return (0); > +} > + > +static int > +hpet_close(struct cdev *cdev, int fflag, int devtype, struct thread *td) > +{ > + struct hpet_softc *sc; > + > + sc = cdev->si_drv1; > + sc->devinuse = 0; > + > + 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; > + > + return (0); > +} > + > /* Discover the HPET via the ACPI table of the same name. */ > static void > hpet_identify(driver_t *driver, device_t parent) > @@ -701,6 +761,26 @@ 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"); > + } else > + device_printf(dev, "could not create /dev/hpet%d\n", > + device_get_unit(dev)); > + > return (0); > } > > -- Andriy Gapon