From owner-svn-src-all@FreeBSD.ORG Mon Apr 28 17:58:42 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 735209AF; Mon, 28 Apr 2014 17:58:42 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5C2801BD2; Mon, 28 Apr 2014 17:58:42 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s3SHwgBA061897; Mon, 28 Apr 2014 17:58:42 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s3SHwehW061889; Mon, 28 Apr 2014 17:58:40 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201404281758.s3SHwehW061889@svn.freebsd.org> From: Marcel Moolenaar Date: Mon, 28 Apr 2014 17:58:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r265055 - in head: share/man/man4 sys/dev/proto sys/modules sys/modules/proto X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 Apr 2014 17:58:42 -0000 Author: marcel Date: Mon Apr 28 17:58:40 2014 New Revision: 265055 URL: http://svnweb.freebsd.org/changeset/base/265055 Log: Add proto(4): A driver for prototyping and diagnostics. It exposes I/O resources to user space, so that programs can peek and poke at the hardware. It does not itself have knowledge about the hardware device it attaches to. Sponsored by: Juniper Networks, Inc. Added: head/share/man/man4/proto.4 (contents, props changed) head/sys/dev/proto/ head/sys/dev/proto/proto.h (contents, props changed) head/sys/dev/proto/proto_bus_pci.c (contents, props changed) head/sys/dev/proto/proto_core.c (contents, props changed) head/sys/dev/proto/proto_dev.h (contents, props changed) head/sys/modules/proto/ head/sys/modules/proto/Makefile (contents, props changed) Modified: head/share/man/man4/Makefile head/sys/modules/Makefile Modified: head/share/man/man4/Makefile ============================================================================== --- head/share/man/man4/Makefile Mon Apr 28 15:03:52 2014 (r265054) +++ head/share/man/man4/Makefile Mon Apr 28 17:58:40 2014 (r265055) @@ -378,6 +378,7 @@ MAN= aac.4 \ ppc.4 \ ppi.4 \ procdesc.4 \ + proto.4 \ psm.4 \ pst.4 \ pt.4 \ Added: head/share/man/man4/proto.4 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/share/man/man4/proto.4 Mon Apr 28 17:58:40 2014 (r265055) @@ -0,0 +1,121 @@ +.\" +.\" Copyright (c) 2014 Marcel Moolenaar +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd April 21, 2014 +.Dt PROTO 4 +.Os +.\" +.Sh NAME +.Nm proto +.Nd Driver for prototyping and H/W diagnostics +.\" +.Sh SYNOPSIS +.Cd "device proto" +.\" +.Sh DESCRIPTION +The +.Nm +device driver attaches to PCI devices when no other device drivers are +present and creates device special files for all resources associated +with the device. +The driver itself has no knowledge of the device it attaches to. +Programs can open these device special files and peform register-level +reads and writes. +As such, the +.Nm +device driver is nothing but a conduit or gateway between user space +programs and the hardware device. +.Pp +Examples for why this is useful include hardware diagnostics and prototyping. +In both these use cases, it's far more convenient to develop and run the +logic in user space. +Especially hardware diagnostics requires a somewhat user-friendly interface +and adequate reporting. +Neither is done easily as kernel code. +.\" +.Sh FILES +All device special files corresponding to a PCI device are located under +.Pa /dev/proto/pci::: +with +.Pa pci::: +representing the location of the PCI device in the PCI hierarchy. +A location includes: +.Bl -tag -width XXXXXX -compact +.It +The PCI domain number +.It +The PCI bus number +.It +The PCI slot or device number +.It +The PCI function number +.El +.Pp +Every PCI device has a device special file called +.Pa pcicfg . +This device special file gives access to the PCI configuration space. +For each valid base address register (BAR), a device special file is created +that contains the BAR offset and the resource type. +A resource type can be either +.Pa io +or +.Pa mem +representing I/O port or memory mapped I/O space (resp.) +.\" +.Sh EXAMPLES +A single function PCI device in domain 0, on bus 1, in slot 2 and having a +single memory mapped I/O region will have the following device special files: +.Bl -tag -compact +.It Pa /dev/proto/pci0:1:2:0/10.mem +.It Pa /dev/proto/pci0:1:2:0/pcicfg +.El +.\" +.Sh SECURITY CONSIDERATIONS +Because programs have direct access to the hardware, the +.Nm +driver is inherently insecure. +It is not advisable to use this driver on a production machine. +.\" +.Sh MISSING FUNCTIONALITY +The +.Nm +driver does not yet support interrupts. +Since interrupts cannot be handled by the driver itself, they must be converted +into signals and delivered to the program that has registered for interrupts. +.Pp +In order to test the transmission or reception of data, some means of doing +direct memory access (DMA) by the device must be possible. This too much be +under the control of the program. The details of how a program can setup and +initiate DMA still need to be fleshed out. +.Pp +Support for non-PCI devices has not been implemented yet. +.\" +.Sh AUTHORS +The +.Nm +device driver and this manual page were written by +.An Marcel Moolenaar Aq marcel@xcllnt.net . Added: head/sys/dev/proto/proto.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/proto/proto.h Mon Apr 28 17:58:40 2014 (r265055) @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2014 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _DEV_PROTO_H_ +#define _DEV_PROTO_H_ + +#define PROTO_RES_MAX 16 + +#define PROTO_RES_UNUSED 0 +#define PROTO_RES_PCICFG 10 + +struct proto_res { + int r_type; + int r_rid; + struct resource *r_res; + u_long r_size; + union { + void *cookie; + struct cdev *cdev; + } r_u; + uintptr_t r_opened; +}; + +struct proto_softc { + device_t sc_dev; + struct proto_res sc_res[PROTO_RES_MAX]; + int sc_rescnt; +}; + +extern devclass_t proto_devclass; +extern char proto_driver_name[]; + +int proto_add_resource(struct proto_softc *, int, int, struct resource *); + +int proto_attach(device_t dev); +int proto_detach(device_t dev); + +#endif /* _DEV_PROTO_H_ */ Added: head/sys/dev/proto/proto_bus_pci.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/proto/proto_bus_pci.c Mon Apr 28 17:58:40 2014 (r265055) @@ -0,0 +1,112 @@ +/*- + * Copyright (c) 2014 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +static int proto_pci_probe(device_t dev); +static int proto_pci_attach(device_t dev); + +static device_method_t proto_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, proto_pci_probe), + DEVMETHOD(device_attach, proto_pci_attach), + DEVMETHOD(device_detach, proto_detach), + DEVMETHOD_END +}; + +static driver_t proto_pci_driver = { + proto_driver_name, + proto_pci_methods, + sizeof(struct proto_softc), +}; + +static int +proto_pci_probe(device_t dev) +{ + struct sbuf *sb; + + /* For now we only attach to function 0 devices. */ + if (pci_get_function(dev) != 0) + return (ENXIO); + + sb = sbuf_new_auto(); + sbuf_printf(sb, "pci%d:%d:%d:%d", pci_get_domain(dev), + pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev)); + sbuf_finish(sb); + device_set_desc_copy(dev, sbuf_data(sb)); + sbuf_delete(sb); + return (BUS_PROBE_HOOVER); +} + +static int +proto_pci_attach(device_t dev) +{ + struct proto_softc *sc; + struct resource *res; + int bar, rid, type; + + sc = device_get_softc(dev); + + proto_add_resource(sc, PROTO_RES_PCICFG, 0, NULL); + + for (bar = 0; bar < PCIR_MAX_BAR_0; bar++) { + rid = PCIR_BAR(bar); + type = SYS_RES_MEMORY; + res = bus_alloc_resource_any(dev, type, &rid, RF_ACTIVE); + if (res == NULL) { + type = SYS_RES_IOPORT; + res = bus_alloc_resource_any(dev, type, &rid, + RF_ACTIVE); + } + if (res != NULL) + proto_add_resource(sc, type, rid, res); + } + + rid = 0; + type = SYS_RES_IRQ; + res = bus_alloc_resource_any(dev, type, &rid, RF_ACTIVE | RF_SHAREABLE); + if (res != NULL) + proto_add_resource(sc, type, rid, res); + return (proto_attach(dev)); +} + +DRIVER_MODULE(proto, pci, proto_pci_driver, proto_devclass, NULL, NULL); Added: head/sys/dev/proto/proto_core.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/proto/proto_core.c Mon Apr 28 17:58:40 2014 (r265055) @@ -0,0 +1,384 @@ +/*- + * Copyright (c) 2014 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +CTASSERT(SYS_RES_IRQ != PROTO_RES_UNUSED && + SYS_RES_MEMORY != PROTO_RES_UNUSED && + SYS_RES_IOPORT != PROTO_RES_UNUSED); +CTASSERT(SYS_RES_IRQ != PROTO_RES_PCICFG && + SYS_RES_MEMORY != PROTO_RES_PCICFG && + SYS_RES_IOPORT != PROTO_RES_PCICFG); + +devclass_t proto_devclass; +char proto_driver_name[] = "proto"; + +static d_open_t proto_open; +static d_close_t proto_close; +static d_read_t proto_read; +static d_write_t proto_write; +static d_ioctl_t proto_ioctl; +static d_mmap_t proto_mmap; + +struct cdevsw proto_devsw = { + .d_version = D_VERSION, + .d_flags = 0, + .d_name = proto_driver_name, + .d_open = proto_open, + .d_close = proto_close, + .d_read = proto_read, + .d_write = proto_write, + .d_ioctl = proto_ioctl, + .d_mmap = proto_mmap, +}; + +static MALLOC_DEFINE(M_PROTO, "PROTO", "PROTO driver"); + +int +proto_add_resource(struct proto_softc *sc, int type, int rid, + struct resource *res) +{ + struct proto_res *r; + + if (type == PROTO_RES_UNUSED) + return (EINVAL); + if (sc->sc_rescnt == PROTO_RES_MAX) + return (ENOSPC); + + r = sc->sc_res + sc->sc_rescnt++; + r->r_type = type; + r->r_rid = rid; + r->r_res = res; + return (0); +} + +#ifdef notyet +static int +proto_intr(void *arg) +{ + struct proto_softc *sc = arg; + + /* XXX TODO */ + return (FILTER_HANDLED); +} +#endif + +int +proto_attach(device_t dev) +{ + struct proto_softc *sc; + struct proto_res *r; + u_int res; + + sc = device_get_softc(dev); + sc->sc_dev = dev; + + for (res = 0; res < sc->sc_rescnt; res++) { + r = sc->sc_res + res; + switch (r->r_type) { + case SYS_RES_IRQ: + /* XXX TODO */ + break; + case SYS_RES_MEMORY: + case SYS_RES_IOPORT: + r->r_size = rman_get_size(r->r_res); + r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666, + "proto/%s/%02x.%s", device_get_desc(dev), r->r_rid, + (r->r_type == SYS_RES_IOPORT) ? "io" : "mem"); + r->r_u.cdev->si_drv1 = sc; + r->r_u.cdev->si_drv2 = r; + break; + case PROTO_RES_PCICFG: + r->r_size = 4096; + r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666, + "proto/%s/pcicfg", device_get_desc(dev)); + r->r_u.cdev->si_drv1 = sc; + r->r_u.cdev->si_drv2 = r; + break; + } + } + return (0); +} + +int +proto_detach(device_t dev) +{ + struct proto_softc *sc; + struct proto_res *r; + u_int res; + + sc = device_get_softc(dev); + + /* Don't detach if we have open device filess. */ + for (res = 0; res < sc->sc_rescnt; res++) { + r = sc->sc_res + res; + if (r->r_opened) + return (EBUSY); + } + + for (res = 0; res < sc->sc_rescnt; res++) { + r = sc->sc_res + res; + switch (r->r_type) { + case SYS_RES_IRQ: + /* XXX TODO */ + break; + case SYS_RES_MEMORY: + case SYS_RES_IOPORT: + case PROTO_RES_PCICFG: + destroy_dev(r->r_u.cdev); + break; + } + if (r->r_res != NULL) { + bus_release_resource(dev, r->r_type, r->r_rid, + r->r_res); + r->r_res = NULL; + } + r->r_type = PROTO_RES_UNUSED; + } + sc->sc_rescnt = 0; + return (0); +} + +/* + * Device functions + */ + +static int +proto_open(struct cdev *cdev, int oflags, int devtype, struct thread *td) +{ + struct proto_res *r; + + r = cdev->si_drv2; + if (!atomic_cmpset_acq_ptr(&r->r_opened, 0UL, (uintptr_t)td->td_proc)) + return (EBUSY); + return (0); +} + +static int +proto_close(struct cdev *cdev, int fflag, int devtype, struct thread *td) +{ + struct proto_res *r; + + r = cdev->si_drv2; + if (!atomic_cmpset_acq_ptr(&r->r_opened, (uintptr_t)td->td_proc, 0UL)) + return (ENXIO); + return (0); +} + +static int +proto_read(struct cdev *cdev, struct uio *uio, int ioflag) +{ + union { + uint8_t x1[8]; + uint16_t x2[4]; + uint32_t x4[2]; + uint64_t x8[1]; + } buf; + struct proto_softc *sc; + struct proto_res *r; + device_t dev; + off_t ofs; + u_long width; + int error; + + sc = cdev->si_drv1; + dev = sc->sc_dev; + r = cdev->si_drv2; + + width = uio->uio_resid; + if (width < 1 || width > 8 || bitcount16(width) > 1) + return (EIO); + ofs = uio->uio_offset; + if (ofs + width > r->r_size) + return (EIO); + + switch (width) { + case 1: + buf.x1[0] = (r->r_type == PROTO_RES_PCICFG) ? + pci_read_config(dev, ofs, 1) : bus_read_1(r->r_res, ofs); + break; + case 2: + buf.x2[0] = (r->r_type == PROTO_RES_PCICFG) ? + pci_read_config(dev, ofs, 2) : bus_read_2(r->r_res, ofs); + break; + case 4: + buf.x4[0] = (r->r_type == PROTO_RES_PCICFG) ? + pci_read_config(dev, ofs, 4) : bus_read_4(r->r_res, ofs); + break; +#ifndef __i386__ + case 8: + if (r->r_type == PROTO_RES_PCICFG) + return (EINVAL); + buf.x8[0] = bus_read_8(r->r_res, ofs); + break; +#endif + default: + return (EIO); + } + + error = uiomove(&buf, width, uio); + return (error); +} + +static int +proto_write(struct cdev *cdev, struct uio *uio, int ioflag) +{ + union { + uint8_t x1[8]; + uint16_t x2[4]; + uint32_t x4[2]; + uint64_t x8[1]; + } buf; + struct proto_softc *sc; + struct proto_res *r; + device_t dev; + off_t ofs; + u_long width; + int error; + + sc = cdev->si_drv1; + dev = sc->sc_dev; + r = cdev->si_drv2; + + width = uio->uio_resid; + if (width < 1 || width > 8 || bitcount16(width) > 1) + return (EIO); + ofs = uio->uio_offset; + if (ofs + width > r->r_size) + return (EIO); + + error = uiomove(&buf, width, uio); + if (error) + return (error); + + switch (width) { + case 1: + if (r->r_type == PROTO_RES_PCICFG) + pci_write_config(dev, ofs, buf.x1[0], 1); + else + bus_write_1(r->r_res, ofs, buf.x1[0]); + break; + case 2: + if (r->r_type == PROTO_RES_PCICFG) + pci_write_config(dev, ofs, buf.x2[0], 2); + else + bus_write_2(r->r_res, ofs, buf.x2[0]); + break; + case 4: + if (r->r_type == PROTO_RES_PCICFG) + pci_write_config(dev, ofs, buf.x4[0], 4); + else + bus_write_4(r->r_res, ofs, buf.x4[0]); + break; +#ifndef __i386__ + case 8: + if (r->r_type == PROTO_RES_PCICFG) + return (EINVAL); + bus_write_8(r->r_res, ofs, buf.x8[0]); + break; +#endif + default: + return (EIO); + } + + return (0); +} + +static int +proto_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, + struct thread *td) +{ + struct proto_ioc_region *region; + struct proto_res *r; + int error; + + r = cdev->si_drv2; + + error = 0; + switch (cmd) { + case PROTO_IOC_REGION: + region = (struct proto_ioc_region *)data; + region->size = r->r_size; + if (r->r_type == PROTO_RES_PCICFG) + region->address = 0; + else + region->address = rman_get_start(r->r_res); + break; + default: + error = ENOIOCTL; + break; + } + return (error); +} + +static int +proto_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr, + int prot, vm_memattr_t *memattr) +{ + struct proto_res *r; + + r = cdev->si_drv2; + + if (r->r_type != SYS_RES_MEMORY) + return (ENXIO); + if (offset & PAGE_MASK) + return (EINVAL); + if (prot & PROT_EXEC) + return (EACCES); + if (offset >= r->r_size) + return (EINVAL); + *paddr = rman_get_start(r->r_res) + offset; +#ifndef __sparc64__ + *memattr = VM_MEMATTR_UNCACHEABLE; +#endif + return (0); +} Added: head/sys/dev/proto/proto_dev.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/proto/proto_dev.h Mon Apr 28 17:58:40 2014 (r265055) @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2014 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _DEV_PROTO_DEV_H_ +#define _DEV_PROTO_DEV_H_ + +#include + +#define PROTO_IOC_CLASS 'h' + +struct proto_ioc_region { + unsigned long address; + unsigned long size; +}; + +#define PROTO_IOC_REGION _IOWR(PROTO_IOC_CLASS, 1, struct proto_ioc_region) + +#endif /* _DEV_PROTO_H_ */ Modified: head/sys/modules/Makefile ============================================================================== --- head/sys/modules/Makefile Mon Apr 28 15:03:52 2014 (r265054) +++ head/sys/modules/Makefile Mon Apr 28 17:58:40 2014 (r265055) @@ -272,6 +272,7 @@ SUBDIR= \ ppi \ pps \ procfs \ + proto \ pseudofs \ ${_pst} \ pty \ Added: head/sys/modules/proto/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/modules/proto/Makefile Mon Apr 28 17:58:40 2014 (r265055) @@ -0,0 +1,20 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/proto + +KMOD= proto +SRCS= \ + proto_bus_pci.c \ + proto_core.c + +SRCS+= \ + bus_if.h \ + device_if.h \ + pci_if.h \ + +MFILES= \ + dev/pci/pci_if.m \ + kern/bus_if.m \ + kern/device_if.m + +.include