diff --git a/sys/arm/arm/pl190.c b/sys/arm/arm/pl190.c new file mode 100644 index 000000000000..3e3807385fec --- /dev/null +++ b/sys/arm/arm/pl190.c @@ -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)); +} diff --git a/sys/conf/files.arm b/sys/conf/files.arm index 8d7904ab3b50..73fe3c2d2b50 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -1,88 +1,89 @@ # $FreeBSD$ arm/arm/autoconf.c standard arm/arm/bcopy_page.S standard arm/arm/bcopyinout.S standard arm/arm/blockio.S standard arm/arm/bootconfig.c standard arm/arm/bus_space_asm_generic.S standard arm/arm/busdma_machdep.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/busdma_machdep-v6.c optional cpu_arm11 | cpu_cortexa | cpu_mv_pj4b arm/arm/copystr.S standard arm/arm/cpufunc.c standard arm/arm/cpufunc_asm.S standard arm/arm/cpufunc_asm_armv4.S standard arm/arm/db_disasm.c optional ddb arm/arm/db_interface.c optional ddb arm/arm/db_trace.c optional ddb arm/arm/disassem.c optional ddb arm/arm/dump_machdep.c standard arm/arm/elf_machdep.c standard arm/arm/exception.S standard arm/arm/fiq.c standard arm/arm/fiq_subr.S standard arm/arm/fusu.S standard arm/arm/gdb_machdep.c optional gdb arm/arm/identcpu.c standard arm/arm/in_cksum.c optional inet | inet6 arm/arm/in_cksum_arm.S optional inet | inet6 arm/arm/intr.c standard arm/arm/locore.S standard no-obj arm/arm/machdep.c standard 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 arm/arm/sc_machdep.c optional sc arm/arm/setcpsr.S standard arm/arm/setstack.s standard arm/arm/stack_machdep.c optional ddb | stack arm/arm/support.S standard arm/arm/swtch.S standard arm/arm/sys_machdep.c standard arm/arm/trap.c standard arm/arm/uio_machdep.c standard arm/arm/undefined.c standard arm/arm/vectors.S standard arm/arm/vm_machdep.c standard arm/arm/vfp.c optional vfp arm/fpe-arm/armfpe_glue.S optional armfpe arm/fpe-arm/armfpe_init.c optional armfpe arm/fpe-arm/armfpe.S optional armfpe board_id.h standard \ dependency "$S/arm/conf/genboardid.awk $S/arm/conf/mach-types" \ compile-with "${AWK} -f $S/arm/conf/genboardid.awk $S/arm/conf/mach-types > board_id.h" \ no-obj no-implicit-rule before-depend \ clean "board_id.h" cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs compile-with "${ZFS_C}" crypto/blowfish/bf_enc.c optional crypto | ipsec crypto/des/des_enc.c optional crypto | ipsec dev/fb/fb.c optional sc dev/hwpmc/hwpmc_arm.c optional hwpmc dev/kbd/kbd.c optional sc dev/syscons/scgfbrndr.c optional sc dev/syscons/scterm-teken.c optional sc dev/syscons/scvtb.c optional sc font.h optional sc \ compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ no-obj no-implicit-rule before-depend \ clean "font.h ${SC_DFLT_FONT}-8x14 ${SC_DFLT_FONT}-8x16 ${SC_DFLT_FONT}-8x8" kern/subr_dummy_vdso_tc.c standard libkern/arm/divsi3.S standard libkern/arm/ffs.S standard libkern/arm/muldi3.c standard libkern/ashldi3.c standard libkern/ashrdi3.c standard libkern/divdi3.c standard libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard libkern/lshrdi3.c standard libkern/memchr.c optional fdt libkern/moddi3.c standard libkern/qdivrem.c standard libkern/ucmpdi2.c standard libkern/udivdi3.c standard libkern/umoddi3.c standard