svn commit: r273278 - in head/sys: arm/altera/socfpga arm/conf boot/fdt/dts/arm dev/beri
Ruslan Bukin
br at FreeBSD.org
Sun Oct 19 16:26:51 UTC 2014
Author: br
Date: Sun Oct 19 16:26:49 2014
New Revision: 273278
URL: https://svnweb.freebsd.org/changeset/base/273278
Log:
Add driver for BERI soft processor 'ring buffer' device.
Ring device provides a way for communicate to BERI
peripherals such as BERI debug unit and console.
Sponsored by: DARPA, AFRL
Added:
head/sys/arm/conf/SOCKIT-BERI (contents, props changed)
head/sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts (contents, props changed)
head/sys/dev/beri/
head/sys/dev/beri/beri_ring.c (contents, props changed)
Modified:
head/sys/arm/altera/socfpga/files.socfpga
Modified: head/sys/arm/altera/socfpga/files.socfpga
==============================================================================
--- head/sys/arm/altera/socfpga/files.socfpga Sun Oct 19 12:11:25 2014 (r273277)
+++ head/sys/arm/altera/socfpga/files.socfpga Sun Oct 19 16:26:49 2014 (r273278)
@@ -21,3 +21,4 @@ arm/altera/socfpga/socfpga_mp.c option
dev/dwc/if_dwc.c optional dwc
dev/mmc/host/dwmmc.c optional dwmmc
+dev/beri/beri_ring.c optional beri_ring
Added: head/sys/arm/conf/SOCKIT-BERI
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/arm/conf/SOCKIT-BERI Sun Oct 19 16:26:49 2014 (r273278)
@@ -0,0 +1,140 @@
+# Kernel configuration for Terasic SoCKit (Altera Cyclone V SoC).
+#
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
+#
+# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# The handbook is also available locally in /usr/share/doc/handbook
+# if you've installed the doc distribution, otherwise always see the
+# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
+# latest information.
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
+# in NOTES.
+#
+# $FreeBSD$
+
+ident SOCKIT-BERI
+include "../altera/socfpga/std.socfpga"
+
+makeoptions MODULES_OVERRIDE=""
+
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+makeoptions WERROR="-Werror"
+
+options HZ=100
+options SCHED_4BSD # 4BSD scheduler
+options INET # InterNETworking
+options INET6 # IPv6 communications protocols
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
+options GEOM_PART_GPT # GUID partition tables
+options TMPFS # Efficient memory filesystem
+options FFS # Berkeley Fast Filesystem
+options SOFTUPDATES
+options UFS_ACL # Support for access control lists
+options UFS_DIRHASH # Improve performance on big directories
+options MSDOSFS # MSDOS Filesystem
+options CD9660 # ISO 9660 Filesystem
+options PROCFS # Process filesystem (requires PSEUDOFS)
+options PSEUDOFS # Pseudo-filesystem framework
+options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
+options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
+options KTRACE
+options SYSVSHM # SYSV-style shared memory
+options SYSVMSG # SYSV-style message queues
+options SYSVSEM # SYSV-style semaphores
+options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options KBD_INSTALL_CDEV
+options PREEMPTION
+options FREEBSD_BOOT_LOADER
+options VFP # vfp/neon
+
+options SMP
+
+# Debugging
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+options BREAK_TO_DEBUGGER
+#options VERBOSE_SYSINIT # Enable verbose sysinit messages
+options KDB
+options DDB # Enable the kernel debugger
+options INVARIANTS # Enable calls of extra sanity checking
+options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+#options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+#options DIAGNOSTIC
+
+# NFS support
+options NFSCL # Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCLIENT
+
+# Uncomment this for NFS root
+#options NFS_ROOT # NFS usable as /, requires NFSCL
+#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
+#options BOOTP
+#options BOOTP_NFSV3
+#options BOOTP_WIRED_TO=ue0
+
+device mmc # mmc/sd bus
+device mmcsd # mmc/sd flash cards
+device dwmmc
+
+options ROOTDEVNAME=\"ufs:/dev/mmcsd0s4\"
+
+# Pseudo devices
+
+device loop
+device random
+device pty
+device md
+device gpio
+
+# USB support
+options USB_HOST_ALIGN=64 # Align usb buffers to cache line size.
+device usb
+options USB_DEBUG
+#options USB_REQ_DEBUG
+#options USB_VERBOSE
+#device musb
+device dwcotg
+
+device umass
+device scbus # SCSI bus (required for ATA/SCSI)
+device da # Direct Access (disks)
+device pass
+
+# Serial ports
+device uart
+device uart_ns8250
+
+# I2C (TWSI)
+device iic
+device iicbus
+
+# SPI
+device spibus
+
+# BERI specific
+device beri_ring
+
+# Ethernet
+device ether
+device mii
+device smsc
+device smscphy
+device dwc
+
+# USB ethernet support, requires miibus
+device miibus
+device axe # ASIX Electronics USB Ethernet
+device bpf # Berkeley packet filter
+
+#FDT
+options FDT
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=socfpga-sockit-beri.dts
Added: head/sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts Sun Oct 19 16:26:49 2014 (r273278)
@@ -0,0 +1,109 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$
+ */
+
+/dts-v1/;
+
+/include/ "socfpga.dtsi"
+
+/ {
+ model = "Terasic SoCKit";
+ compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+ /* Reserve first page for secondary CPU trampoline code */
+ memreserve = < 0x00000000 0x1000 >;
+
+ memory {
+ device_type = "memory";
+ reg = < 0x00000000 0x40000000 >; /* 1G RAM */
+ };
+
+ SOC: socfpga {
+ serial0: serial at ffc02000 {
+ status = "okay";
+ };
+
+ usb1: usb at ffb40000 {
+ status = "okay";
+ };
+
+ gmac1: ethernet at ff702000 {
+ status = "okay";
+ };
+
+ mmc: dwmmc at ff704000 {
+ status = "okay";
+ num-slots = <1>;
+ supports-highspeed;
+ broken-cd;
+ bus-frequency = <25000000>;
+
+ slot at 0 {
+ reg = <0>;
+ bus-width = <4>;
+ };
+ };
+
+ beri_debug: ring at c0000000 {
+ compatible = "sri-cambridge,beri-ring";
+ reg = <0xc0000000 0x3000>;
+ interrupts = < 72 73 >;
+ interrupt-parent = <&GIC>;
+ device_name = "beri_debug";
+ data_size = <0x1000>;
+ data_read = <0x0>;
+ data_write = <0x1000>;
+ control_read = <0x2000>;
+ control_write = <0x2010>;
+ status = "okay";
+ };
+
+ beri_console: ring at c0004000 {
+ compatible = "sri-cambridge,beri-ring";
+ reg = <0xc0004000 0x3000>;
+ interrupts = < 74 75 >;
+ interrupt-parent = <&GIC>;
+ device_name = "beri_console";
+ data_size = <0x1000>;
+ data_read = <0x0>;
+ data_write = <0x1000>;
+ control_read = <0x2000>;
+ control_write = <0x2010>;
+ status = "okay";
+ };
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
Added: head/sys/dev/beri/beri_ring.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/dev/beri/beri_ring.c Sun Oct 19 16:26:49 2014 (r273278)
@@ -0,0 +1,529 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ */
+
+/*
+ * SRI-Cambridge BERI soft processor <-> ARM core ring buffer.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/event.h>
+#include <sys/selinfo.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#define READ4(_sc, _reg) \
+ bus_read_4((_sc)->res[0], _reg)
+#define WRITE4(_sc, _reg, _val) \
+ bus_write_4((_sc)->res[0], _reg, _val)
+
+#define CDES_INT_EN (1 << 15)
+#define CDES_CAUSE_MASK 0x3
+#define CDES_CAUSE_SHIFT 13
+#define DEVNAME_MAXLEN 256
+
+typedef struct
+{
+ uint16_t cdes;
+ uint16_t interrupt_level;
+ uint16_t in;
+ uint16_t out;
+} control_reg_t;
+
+struct beri_softc {
+ struct resource *res[3];
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ struct cdev *cdev;
+ device_t dev;
+ void *read_ih;
+ void *write_ih;
+ struct selinfo beri_rsel;
+ struct mtx beri_mtx;
+ int opened;
+
+ char devname[DEVNAME_MAXLEN];
+ int control_read;
+ int control_write;
+ int data_read;
+ int data_write;
+ int data_size;
+};
+
+static struct resource_spec beri_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 1, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static control_reg_t
+get_control_reg(struct beri_softc *sc, int dir)
+{
+ uint32_t offset;
+ uint16_t dst[4];
+ control_reg_t c;
+ uint16_t *cp;
+ int i;
+
+ cp = (uint16_t *)&c;
+
+ offset = dir ? sc->control_write : sc->control_read;
+ ((uint32_t *)dst)[0] = READ4(sc, offset);
+ ((uint32_t *)dst)[1] = READ4(sc, offset + 4);
+
+ for (i = 0; i < 4; i++)
+ cp[i] = dst[3 - i];
+
+ return (c);
+}
+
+static void
+set_control_reg(struct beri_softc *sc, int dir, control_reg_t *c)
+{
+ uint32_t offset;
+ uint16_t src[4];
+ uint16_t *cp;
+ int i;
+
+ cp = (uint16_t *)c;
+
+ for (i = 0; i < 4; i++)
+ src[3 - i] = cp[i];
+
+ offset = dir ? sc->control_write : sc->control_read;
+ WRITE4(sc, offset + 0, ((uint32_t *)src)[0]);
+ WRITE4(sc, offset + 4, ((uint32_t *)src)[1]);
+}
+
+static int
+get_stock(struct beri_softc *sc, int dir, control_reg_t *c)
+{
+ uint32_t fill;
+
+ fill = (c->in - c->out + sc->data_size) % sc->data_size;
+
+ if (dir)
+ return (sc->data_size - fill - 1);
+ else
+ return (fill);
+}
+
+static void
+beri_intr_write(void *arg)
+{
+ struct beri_softc *sc;
+ control_reg_t c;
+
+ sc = arg;
+
+ c = get_control_reg(sc, 1);
+ if (c.cdes & CDES_INT_EN) {
+ c.cdes &= ~(CDES_INT_EN);
+ set_control_reg(sc, 1, &c);
+ }
+
+ mtx_lock(&sc->beri_mtx);
+ selwakeuppri(&sc->beri_rsel, PZERO + 1);
+ KNOTE_LOCKED(&sc->beri_rsel.si_note, 0);
+ mtx_unlock(&sc->beri_mtx);
+}
+
+static void
+beri_intr_read(void *arg)
+{
+ struct beri_softc *sc;
+ control_reg_t c;
+
+ sc = arg;
+
+ c = get_control_reg(sc, 0);
+ if (c.cdes & CDES_INT_EN) {
+ c.cdes &= ~(CDES_INT_EN);
+ set_control_reg(sc, 0, &c);
+ }
+
+ mtx_lock(&sc->beri_mtx);
+ selwakeuppri(&sc->beri_rsel, PZERO + 1);
+ KNOTE_LOCKED(&sc->beri_rsel.si_note, 0);
+ mtx_unlock(&sc->beri_mtx);
+}
+
+static int
+beri_open(struct cdev *dev, int flags __unused,
+ int fmt __unused, struct thread *td __unused)
+{
+ struct beri_softc *sc;
+ control_reg_t c;
+
+ sc = dev->si_drv1;
+
+ if (sc->opened)
+ return (1);
+
+ /* Setup interrupt handlers */
+ if (bus_setup_intr(sc->dev, sc->res[1], INTR_TYPE_BIO | INTR_MPSAFE,
+ NULL, beri_intr_read, sc, &sc->read_ih)) {
+ device_printf(sc->dev, "Unable to setup read intr\n");
+ return (1);
+ }
+ if (bus_setup_intr(sc->dev, sc->res[2], INTR_TYPE_BIO | INTR_MPSAFE,
+ NULL, beri_intr_write, sc, &sc->write_ih)) {
+ device_printf(sc->dev, "Unable to setup write intr\n");
+ return (1);
+ }
+
+ sc->opened = 1;
+
+ /* Clear write buffer */
+ c = get_control_reg(sc, 1);
+ c.in = c.out;
+ c.cdes = 0;
+ set_control_reg(sc, 1, &c);
+
+ /* Clear read buffer */
+ c = get_control_reg(sc, 0);
+ c.out = c.in;
+ c.cdes = 0;
+ set_control_reg(sc, 0, &c);
+
+ return (0);
+}
+
+static int
+beri_close(struct cdev *dev, int flags __unused,
+ int fmt __unused, struct thread *td __unused)
+{
+ struct beri_softc *sc;
+
+ sc = dev->si_drv1;
+
+ if (sc->opened) {
+ sc->opened = 0;
+
+ /* Unsetup interrupt handlers */
+ bus_teardown_intr(sc->dev, sc->res[1], sc->read_ih);
+ bus_teardown_intr(sc->dev, sc->res[2], sc->write_ih);
+ }
+
+ return (0);
+}
+
+static int
+beri_rdwr(struct cdev *dev, struct uio *uio, int ioflag)
+{
+ struct beri_softc *sc;
+ uint32_t offset;
+ control_reg_t c;
+ uint16_t *ptr;
+ uint8_t *dst;
+ int stock;
+ int dir;
+ int amount;
+ int count;
+
+ sc = dev->si_drv1;
+
+ dir = uio->uio_rw ? 1 : 0;
+
+ c = get_control_reg(sc, dir);
+ stock = get_stock(sc, dir, &c);
+ if (stock < uio->uio_resid) {
+ device_printf(sc->dev, "Err: no data/space available\n");
+ return (1);
+ }
+
+ amount = uio->uio_resid;
+ ptr = dir ? &c.in : &c.out;
+ count = (sc->data_size - *ptr);
+
+ offset = dir ? sc->data_write : sc->data_read;
+ dst = (uint8_t *)(sc->bsh + offset);
+
+ if (amount <= count) {
+ uiomove(dst + *ptr, amount, uio);
+ } else {
+ uiomove(dst + *ptr, count, uio);
+ uiomove(dst, (amount - count), uio);
+ }
+
+ *ptr = (*ptr + amount) % sc->data_size;
+ set_control_reg(sc, dir, &c);
+
+ return (0);
+}
+
+static int
+beri_kqread(struct knote *kn, long hint)
+{
+ struct beri_softc *sc;
+ control_reg_t c;
+ int stock;
+
+ sc = kn->kn_hook;
+
+ c = get_control_reg(sc, 0);
+ stock = get_stock(sc, 0, &c);
+ if (stock) {
+ kn->kn_data = stock;
+ return (1);
+ }
+
+ kn->kn_data = 0;
+
+ /* Wait at least one new byte in buffer */
+ c.interrupt_level = 1;
+
+ /* Enable interrupts */
+ c.cdes |= (CDES_INT_EN);
+ set_control_reg(sc, 0, &c);
+
+ return (0);
+}
+
+static int
+beri_kqwrite(struct knote *kn, long hint)
+{
+ struct beri_softc *sc;
+ control_reg_t c;
+ int stock;
+
+ sc = kn->kn_hook;
+
+ c = get_control_reg(sc, 1);
+ stock = get_stock(sc, 1, &c);
+ if (stock) {
+ kn->kn_data = stock;
+ return (1);
+ }
+
+ kn->kn_data = 0;
+
+ /* Wait at least one free position in buffer */
+ c.interrupt_level = sc->data_size - 2;
+
+ /* Enable interrupts */
+ c.cdes |= (CDES_INT_EN);
+ set_control_reg(sc, 1, &c);
+
+ return (0);
+}
+
+static void
+beri_kqdetach(struct knote *kn)
+{
+ struct beri_softc *sc;
+
+ sc = kn->kn_hook;
+
+ knlist_remove(&sc->beri_rsel.si_note, kn, 0);
+}
+
+static struct filterops beri_read_filterops = {
+ .f_isfd = 1,
+ .f_attach = NULL,
+ .f_detach = beri_kqdetach,
+ .f_event = beri_kqread,
+};
+
+static struct filterops beri_write_filterops = {
+ .f_isfd = 1,
+ .f_attach = NULL,
+ .f_detach = beri_kqdetach,
+ .f_event = beri_kqwrite,
+};
+
+static int
+beri_kqfilter(struct cdev *dev, struct knote *kn)
+{
+ struct beri_softc *sc;
+
+ sc = dev->si_drv1;
+
+ switch(kn->kn_filter) {
+ case EVFILT_READ:
+ kn->kn_fop = &beri_read_filterops;
+ break;
+ case EVFILT_WRITE:
+ kn->kn_fop = &beri_write_filterops;
+ break;
+ default:
+ return(EINVAL);
+ }
+
+ kn->kn_hook = sc;
+ knlist_add(&sc->beri_rsel.si_note, kn, 0);
+
+ return (0);
+}
+
+static struct cdevsw beri_cdevsw = {
+ .d_version = D_VERSION,
+ .d_open = beri_open,
+ .d_close = beri_close,
+ .d_write = beri_rdwr,
+ .d_read = beri_rdwr,
+ .d_kqfilter = beri_kqfilter,
+ .d_name = "beri ring buffer",
+};
+
+static int
+parse_fdt(struct beri_softc *sc)
+{
+ pcell_t dts_value[0];
+ phandle_t node;
+ int len;
+
+ if ((node = ofw_bus_get_node(sc->dev)) == -1)
+ return (ENXIO);
+
+ /* get device name */
+ if (OF_getprop(ofw_bus_get_node(sc->dev), "device_name",
+ &sc->devname, sizeof(sc->devname)) <= 0) {
+ device_printf(sc->dev, "Can't get device_name\n");
+ return (ENXIO);
+ }
+
+ if ((len = OF_getproplen(node, "data_size")) <= 0)
+ return (ENXIO);
+ OF_getencprop(node, "data_size", dts_value, len);
+ sc->data_size = dts_value[0];
+
+ if ((len = OF_getproplen(node, "data_read")) <= 0)
+ return (ENXIO);
+ OF_getencprop(node, "data_read", dts_value, len);
+ sc->data_read = dts_value[0];
+
+ if ((len = OF_getproplen(node, "data_write")) <= 0)
+ return (ENXIO);
+ OF_getencprop(node, "data_write", dts_value, len);
+ sc->data_write = dts_value[0];
+
+ if ((len = OF_getproplen(node, "control_read")) <= 0)
+ return (ENXIO);
+ OF_getencprop(node, "control_read", dts_value, len);
+ sc->control_read = dts_value[0];
+
+ if ((len = OF_getproplen(node, "control_write")) <= 0)
+ return (ENXIO);
+ OF_getencprop(node, "control_write", dts_value, len);
+ sc->control_write = dts_value[0];
+
+ return (0);
+}
+
+static int
+beri_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (!ofw_bus_is_compatible(dev, "sri-cambridge,beri-ring"))
+ return (ENXIO);
+
+ device_set_desc(dev, "SRI-Cambridge BERI ring buffer");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+beri_attach(device_t dev)
+{
+ struct beri_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ if (bus_alloc_resources(dev, beri_spec, sc->res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ /* Memory interface */
+ sc->bst = rman_get_bustag(sc->res[0]);
+ sc->bsh = rman_get_bushandle(sc->res[0]);
+
+ if (parse_fdt(sc)) {
+ device_printf(sc->dev, "Can't get FDT values\n");
+ return (ENXIO);
+ }
+
+ sc->cdev = make_dev(&beri_cdevsw, 0, UID_ROOT, GID_WHEEL,
+ S_IRWXU, "%s", sc->devname);
+ if (sc->cdev == NULL) {
+ device_printf(dev, "Failed to create character device.\n");
+ return (ENXIO);
+ }
+
+ sc->cdev->si_drv1 = sc;
+
+ mtx_init(&sc->beri_mtx, "beri_mtx", NULL, MTX_DEF);
+ knlist_init_mtx(&sc->beri_rsel.si_note, &sc->beri_mtx);
+
+ return (0);
+}
+
+static device_method_t beri_methods[] = {
+ DEVMETHOD(device_probe, beri_probe),
+ DEVMETHOD(device_attach, beri_attach),
+ { 0, 0 }
+};
+
+static driver_t beri_driver = {
+ "beri_ring",
+ beri_methods,
+ sizeof(struct beri_softc),
+};
+
+static devclass_t beri_devclass;
+
+DRIVER_MODULE(beri_ring, simplebus, beri_driver, beri_devclass, 0, 0);
More information about the svn-src-all
mailing list