Module Name: src Committed By: nisimura Date: Wed Aug 19 06:22:54 UTC 2009
Modified Files: src/sys/arch/powerpc/pic: files.pic picvar.h Added Files: src/sys/arch/powerpc/pic: pic_mpcsoc.c Log Message: - Have pic_mpcsoc.c to adapt variations of Moto/Freescale OpenPIC compliant interrupt controllers. Mostly the refrain of pic_openpic.c and shall be useful for 85xx/86xx/QorIQ and Tundra product lines. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/arch/powerpc/pic/files.pic cvs rdiff -u -r0 -r1.1 src/sys/arch/powerpc/pic/pic_mpcsoc.c cvs rdiff -u -r1.5 -r1.6 src/sys/arch/powerpc/pic/picvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/powerpc/pic/files.pic diff -u src/sys/arch/powerpc/pic/files.pic:1.3 src/sys/arch/powerpc/pic/files.pic:1.4 --- src/sys/arch/powerpc/pic/files.pic:1.3 Thu Jan 17 23:42:59 2008 +++ src/sys/arch/powerpc/pic/files.pic Wed Aug 19 06:22:54 2009 @@ -1,5 +1,5 @@ # -# $NetBSD: files.pic,v 1.3 2008/01/17 23:42:59 garbled Exp $ +# $NetBSD: files.pic,v 1.4 2009/08/19 06:22:54 nisimura Exp $ # # generic PIC abstraction @@ -10,16 +10,19 @@ define pic_distopenpic define pic_prepivr define pic_i8259 +define pic_mpcsoc defflag opt_interrupt.h PIC_OPENPIC: pic_openpic defflag opt_interrupt.h PIC_DISTOPENPIC: pic_distopenpic defflag opt_interrupt.h PIC_PREPIVR: pic_prepivr defflag opt_interrupt.h PIC_I8259: pic_i8259 +defflag opt_interrupt.h PIC_MPCSOC: pic_mpcsoc defflag opt_interrupt.h OPENPIC_DISTRIBUTE file arch/powerpc/pic/pic_openpic.c pic_openpic needs-flag file arch/powerpc/pic/pic_distopenpic.c pic_distopenpic needs-flag file arch/powerpc/pic/pic_prepivr.c pic_prepivr needs-flag file arch/powerpc/pic/pic_i8259.c pic_i8259 needs-flag +file arch/powerpc/pic/pic_mpcsoc.c pic_mpcsoc file arch/powerpc/pic/i8259_common.c pic_prepivr | pic_i8259 -file arch/powerpc/pic/openpic_common.c pic_openpic | pic_distopenpic +file arch/powerpc/pic/openpic_common.c pic_openpic | pic_distopenpic | pic_mpcsoc Index: src/sys/arch/powerpc/pic/picvar.h diff -u src/sys/arch/powerpc/pic/picvar.h:1.5 src/sys/arch/powerpc/pic/picvar.h:1.6 --- src/sys/arch/powerpc/pic/picvar.h:1.5 Tue Apr 29 06:53:02 2008 +++ src/sys/arch/powerpc/pic/picvar.h Wed Aug 19 06:22:54 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: picvar.h,v 1.5 2008/04/29 06:53:02 martin Exp $ */ +/* $NetBSD: picvar.h,v 1.6 2009/08/19 06:22:54 nisimura Exp $ */ /*- * Copyright (c) 2007 Michael Lorenz @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: picvar.h,v 1.5 2008/04/29 06:53:02 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: picvar.h,v 1.6 2009/08/19 06:22:54 nisimura Exp $"); #ifndef PIC_VAR_H #define PIC_VAR_H @@ -113,6 +113,8 @@ struct pic_ops *setup_distributed_openpic(void *, int, void **, int *); struct pic_ops *setup_prepivr(int); struct pic_ops *setup_i8259(void); +struct pic_ops *setup_mpcpic(void *); +void mpcpic_reserv16(void); /* i8259 common decls */ void i8259_initialize(void); Added files: Index: src/sys/arch/powerpc/pic/pic_mpcsoc.c diff -u /dev/null src/sys/arch/powerpc/pic/pic_mpcsoc.c:1.1 --- /dev/null Wed Aug 19 06:22:54 2009 +++ src/sys/arch/powerpc/pic/pic_mpcsoc.c Wed Aug 19 06:22:54 2009 @@ -0,0 +1,204 @@ +/* $NetBSD: pic_mpcsoc.c,v 1.1 2009/08/19 06:22:54 nisimura Exp $ */ + +/*- + * Copyright (c) 2007 Michael Lorenz + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: pic_mpcsoc.c,v 1.1 2009/08/19 06:22:54 nisimura Exp $"); + +#include <sys/param.h> +#include <sys/malloc.h> +#include <sys/kernel.h> + +#include <uvm/uvm_extern.h> + +#include <machine/pio.h> +#include <powerpc/openpic.h> + +#include <arch/powerpc/pic/picvar.h> + +#include "opt_interrupt.h" + +static void mpcpic_enable_irq(struct pic_ops *, int, int); +static void mpcpic_disable_irq(struct pic_ops *, int); +static void mpcpic_establish_irq(struct pic_ops *, int, int, int); +static void mpcpic_finish_setup(struct pic_ops *); + +static u_int steer8245[] = { + 0x10200, /* external irq 0 direct/serial */ + 0x10220, /* external irq 1 direct/serial */ + 0x10240, /* external irq 2 direct/serial */ + 0x10260, /* external irq 3 direct/serial */ + 0x10280, /* external irq 4 direct/serial */ + 0x102a0, /* external irq 5 serial mode */ + 0x102c0, /* external irq 6 serial mode */ + 0x102e0, /* external irq 7 serial mode */ + 0x10300, /* external irq 8 serial mode */ + 0x10320, /* external irq 9 serial mode */ + 0x10340, /* external irq 10 serial mode */ + 0x10360, /* external irq 11 serial mode */ + 0x10380, /* external irq 12 serial mode */ + 0x103a0, /* external irq 13 serial mode */ + 0x103c0, /* external irq 14 serial mode */ + 0x103e0, /* external irq 15 serial mode */ + 0x11020, /* I2C */ + 0x11040, /* DMA 0 */ + 0x11060, /* DMA 1 */ + 0x110c0, /* MU/I2O */ + 0x01120, /* Timer 0 */ + 0x01160, /* Timer 1 */ + 0x011a0, /* Timer 2 */ + 0x011e0, /* Timer 3 */ + 0x11120, /* DUART 0, MPC8245 */ + 0x11140, /* DUART 1, MPC8245 */ +}; +#define MPCPIC_IVEC(n) (steer8245[(n)]) +#define MPCPIC_IDST(n) (steer8245[(n)] + 0x10) + +static int i8259iswired = 0; + +struct pic_ops * +setup_mpcpic(void *addr) +{ + struct openpic_ops *ops; + struct pic_ops *self; + int irq; + u_int x; + + openpic_base = addr; + ops = malloc(sizeof(struct openpic_ops), M_DEVBUF, M_NOWAIT); + KASSERT(ops != NULL); + self = &ops->pic; + + x = openpic_read(OPENPIC_FEATURE); + if (((x & 0x07ff0000) >> 16) == 0) + panic("setup_mpcpic() called on distributed openpic"); + + aprint_normal("OpenPIC Version 1.%d: " + "Supports %d CPUs and %d interrupt sources.\n", + x & 0xff, ((x & 0x1f00) >> 8) + 1, ((x & 0x07ff0000) >> 16) + 1); + +#ifdef PIC_I8259 + i8259iswired = 1; +#endif + self->pic_numintrs = ((x & 0x07ff0000) >> 16) + 1; + self->pic_cookie = addr; + self->pic_enable_irq = mpcpic_enable_irq; + self->pic_reenable_irq = mpcpic_enable_irq; + self->pic_disable_irq = mpcpic_disable_irq; + self->pic_get_irq = opic_get_irq; + self->pic_ack_irq = opic_ack_irq; + self->pic_establish_irq = mpcpic_establish_irq; + self->pic_finish_setup = mpcpic_finish_setup; + ops->isu = NULL; + ops->nrofisus = 0; /* internal only */ + ops->flags = 0; /* no flags (yet) */ + ops->irq_per = NULL; /* internal ISU only */ + strcpy(self->pic_name, "mpcpic"); + pic_add(self); + + openpic_set_priority(0, 15); + for (irq = 0; irq < self->pic_numintrs; irq++) { + /* make sure to keep disabled */ + openpic_write(MPCPIC_IVEC(irq), OPENPIC_IMASK); + /* send all interrupts to CPU 0 */ + openpic_write(MPCPIC_IDST(irq), 1 << 0); + } + openpic_write(OPENPIC_SPURIOUS_VECTOR, 0xff); + openpic_set_priority(0, 0); + + /* clear all pending interrunts */ + for (irq = 0; irq < self->pic_numintrs; irq++) { + openpic_read_irq(0); + openpic_eoi(0); + } + +#if 0 + printf("timebase freq=%d\n", openpic_read(0x10f0)); +#endif + return self; +} + +void +mpcpic_reserv16() +{ + extern int max_base; /* intr.c */ + + /* + * reserve 16 irq slot for the case when no i8259 exists to use. + */ + max_base += 16; +} + +static void +mpcpic_establish_irq(struct pic_ops *pic, int irq, int type, int pri) +{ + int realpri = max(1, min(15, pri)); + u_int x; + + x = irq; + x |= OPENPIC_IMASK; + x |= (i8259iswired && irq == 0) ? + OPENPIC_POLARITY_POSITIVE : OPENPIC_POLARITY_NEGATIVE; + x |= (type == IST_EDGE) ? OPENPIC_SENSE_EDGE : OPENPIC_SENSE_LEVEL; + x |= realpri << OPENPIC_PRIORITY_SHIFT; + openpic_write(MPCPIC_IVEC(irq), x); + + aprint_debug("%s: setting IRQ %d to priority %d\n", __func__, irq, + realpri); +} + +static void +mpcpic_enable_irq(struct pic_ops *pic, int irq, int type) +{ + u_int x; + + x = openpic_read(MPCPIC_IVEC(irq)); + x &= ~OPENPIC_IMASK; + openpic_write(MPCPIC_IVEC(irq), x); +} + +static void +mpcpic_disable_irq(struct pic_ops *pic, int irq) +{ + u_int x; + + x = openpic_read(MPCPIC_IVEC(irq)); + x |= OPENPIC_IMASK; + openpic_write(MPCPIC_IVEC(irq), x); +} + +static void +mpcpic_finish_setup(struct pic_ops *pic) +{ + uint32_t cpumask = 1; + int i; + + for (i = 0; i < pic->pic_numintrs; i++) { + /* send all interrupts to all active CPUs */ + openpic_write(MPCPIC_IDST(i), cpumask); + } +}