From owner-svn-src-head@FreeBSD.ORG Thu Dec 13 23:03:38 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 21354720; Thu, 13 Dec 2012 23:03:38 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 06FAF8FC13; Thu, 13 Dec 2012 23:03:38 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qBDN3bpA032295; Thu, 13 Dec 2012 23:03:37 GMT (envelope-from gonzo@svn.freebsd.org) Received: (from gonzo@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qBDN3bKf032293; Thu, 13 Dec 2012 23:03:37 GMT (envelope-from gonzo@svn.freebsd.org) Message-Id: <201212132303.qBDN3bKf032293@svn.freebsd.org> From: Oleksandr Tymoshenko Date: Thu, 13 Dec 2012 23:03:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r244195 - in head/sys: arm/arm conf X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 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: Thu, 13 Dec 2012 23:03:38 -0000 Author: gonzo Date: Thu Dec 13 23:03:37 2012 New Revision: 244195 URL: http://svnweb.freebsd.org/changeset/base/244195 Log: Add driver for PrimeCell Vectored Interrupt Controller (PL190) Added: head/sys/arm/arm/pl190.c (contents, props changed) Modified: head/sys/conf/files.arm Added: head/sys/arm/arm/pl190.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/arm/pl190.c Thu Dec 13 23:03:37 2012 (r244195) @@ -0,0 +1,187 @@ +/*- + * Copyright (c) 2012 Oleksandr Tymoshenko + * 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 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. + */ + + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef DEBUG +#define dprintf(fmt, args...) printf(fmt, ##args) +#else +#define dprintf(fmt, args...) +#endif + +#define VICIRQSTATUS 0x000 +#define VICFIQSTATUS 0x004 +#define VICRAWINTR 0x008 +#define VICINTSELECT 0x00C +#define VICINTENABLE 0x010 +#define VICINTENCLEAR 0x014 +#define VICSOFTINT 0x018 +#define VICSOFTINTCLEAR 0x01C +#define VICPROTECTION 0x020 +#define VICPERIPHID 0xFE0 +#define VICPRIMECELLID 0xFF0 + +#define VIC_NIRQS 32 + +struct pl190_intc_softc { + device_t sc_dev; + struct resource * intc_res; +}; + +static struct pl190_intc_softc *pl190_intc_sc = NULL; + +#define intc_vic_read_4(reg) \ + bus_read_4(pl190_intc_sc->intc_res, (reg)) +#define intc_vic_write_4(reg, val) \ + bus_write_4(pl190_intc_sc->intc_res, (reg), (val)) + +static int +pl190_intc_probe(device_t dev) +{ + if (!ofw_bus_is_compatible(dev, "arm,versatile-vic")) + return (ENXIO); + device_set_desc(dev, "ARM PL190 VIC"); + return (BUS_PROBE_DEFAULT); +} + +static int +pl190_intc_attach(device_t dev) +{ + struct pl190_intc_softc *sc = device_get_softc(dev); + uint32_t id; + int i, rid; + + sc->sc_dev = dev; + + if (pl190_intc_sc) + return (ENXIO); + + /* Request memory resources */ + rid = 0; + sc->intc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->intc_res == NULL) { + device_printf(dev, "Error: could not allocate memory resources\n"); + return (ENXIO); + } + + pl190_intc_sc = sc; + /* + * All interrupts should use IRQ line + */ + intc_vic_write_4(VICINTSELECT, 0x00000000); + /* Disable all interrupts */ + intc_vic_write_4(VICINTENCLEAR, 0xffffffff); + /* Enable INT31, SIC IRQ */ + intc_vic_write_4(VICINTENABLE, (1 << 31)); + + id = 0; + for (i = 3; i >= 0; i--) { + id = (id << 8) | + (intc_vic_read_4(VICPERIPHID + i*4) & 0xff); + } + + device_printf(dev, "Peripheral ID: %08x\n", id); + + id = 0; + for (i = 3; i >= 0; i--) { + id = (id << 8) | + (intc_vic_read_4(VICPRIMECELLID + i*4) & 0xff); + } + + device_printf(dev, "PrimeCell ID: %08x\n", id); + + return (0); +} + +static device_method_t pl190_intc_methods[] = { + DEVMETHOD(device_probe, pl190_intc_probe), + DEVMETHOD(device_attach, pl190_intc_attach), + { 0, 0 } +}; + +static driver_t pl190_intc_driver = { + "intc", + pl190_intc_methods, + sizeof(struct pl190_intc_softc), +}; + +static devclass_t pl190_intc_devclass; + +DRIVER_MODULE(intc, simplebus, pl190_intc_driver, pl190_intc_devclass, 0, 0); + +int +arm_get_next_irq(int last_irq) +{ + uint32_t pending; + int32_t irq = last_irq + 1; + + /* Sanity check */ + if (irq < 0) + irq = 0; + + pending = intc_vic_read_4(VICIRQSTATUS); + while (irq < VIC_NIRQS) { + if (pending & (1 << irq)) + return (irq); + irq++; + } + + return (-1); +} + +void +arm_mask_irq(uintptr_t nb) +{ + + dprintf("%s: %d\n", __func__, nb); + intc_vic_write_4(VICINTENCLEAR, (1 << nb)); +} + +void +arm_unmask_irq(uintptr_t nb) +{ + + dprintf("%s: %d\n", __func__, nb); + intc_vic_write_4(VICINTENABLE, (1 << nb)); +} Modified: head/sys/conf/files.arm ============================================================================== --- head/sys/conf/files.arm Thu Dec 13 22:03:07 2012 (r244194) +++ head/sys/conf/files.arm Thu Dec 13 23:03:37 2012 (r244195) @@ -32,6 +32,7 @@ arm/arm/mem.c optional mem arm/arm/minidump_machdep.c optional mem arm/arm/mp_machdep.c optional smp arm/arm/nexus.c standard +arm/arm/pl190.c optional pl190 arm/arm/pl310.c optional pl310 arm/arm/pmap.c optional cpu_arm9 | cpu_arm9e | cpu_fa526 | cpu_sa1100 | cpu_sa1110 | cpu_xscale_80219 | cpu_xscale_80321 | cpu_xscale_81342 | cpu_xscale_ixp425 | cpu_xscale_ixp435 | cpu_xscale_pxa2x0 arm/arm/pmap-v6.c optional cpu_arm11 | cpu_cortexa | cpu_mv_pj4b