The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/powerpc/powerpc/openpic.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (C) 2002 Benno Rice.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
   15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   17  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   18  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   21  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   23  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24  *
   25  * $FreeBSD$
   26  */
   27 
   28 #include <sys/param.h>
   29 #include <sys/systm.h>
   30 #include <sys/bus.h>
   31 #include <sys/conf.h>
   32 #include <sys/kernel.h>
   33 #include <sys/rman.h>
   34 
   35 #include <machine/bus.h>
   36 #include <machine/intr.h>
   37 #include <machine/intr_machdep.h>
   38 #include <machine/md_var.h>
   39 #include <machine/pio.h>
   40 #include <machine/resource.h>
   41 
   42 #include <vm/vm.h>
   43 #include <vm/pmap.h>
   44 
   45 #include <machine/openpicreg.h>
   46 #include <machine/openpicvar.h>
   47 
   48 #include "pic_if.h"
   49 
   50 devclass_t openpic_devclass;
   51 
   52 /*
   53  * Local routines
   54  */
   55 
   56 static __inline uint32_t
   57 openpic_read(struct openpic_softc *sc, u_int reg)
   58 {
   59         return (bus_space_read_4(sc->sc_bt, sc->sc_bh, reg));
   60 }
   61 
   62 static __inline void
   63 openpic_write(struct openpic_softc *sc, u_int reg, uint32_t val)
   64 {
   65         bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val);
   66 }
   67 
   68 static __inline void
   69 openpic_set_priority(struct openpic_softc *sc, int cpu, int pri)
   70 {
   71         uint32_t x;
   72 
   73         x = openpic_read(sc, OPENPIC_CPU_PRIORITY(cpu));
   74         x &= ~OPENPIC_CPU_PRIORITY_MASK;
   75         x |= pri;
   76         openpic_write(sc, OPENPIC_CPU_PRIORITY(cpu), x);
   77 }
   78 
   79 int
   80 openpic_attach(device_t dev)
   81 {
   82         struct openpic_softc *sc;
   83         u_int     irq;
   84         u_int32_t x;
   85 
   86         sc = device_get_softc(dev);
   87         sc->sc_dev = dev;
   88 
   89         sc->sc_rid = 0;
   90         sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid,
   91             RF_ACTIVE);
   92 
   93         if (sc->sc_memr == NULL) {
   94                 device_printf(dev, "Could not alloc mem resource!\n");
   95                 return (ENXIO);
   96         }
   97 
   98         sc->sc_bt = rman_get_bustag(sc->sc_memr);
   99         sc->sc_bh = rman_get_bushandle(sc->sc_memr);
  100 
  101         x = openpic_read(sc, OPENPIC_FEATURE);
  102         switch (x & OPENPIC_FEATURE_VERSION_MASK) {
  103         case 1:
  104                 sc->sc_version = "1.0";
  105                 break;
  106         case 2:
  107                 sc->sc_version = "1.2";
  108                 break;
  109         case 3:
  110                 sc->sc_version = "1.3";
  111                 break;
  112         default:
  113                 sc->sc_version = "unknown";
  114                 break;
  115         }
  116 
  117         sc->sc_ncpu = ((x & OPENPIC_FEATURE_LAST_CPU_MASK) >>
  118             OPENPIC_FEATURE_LAST_CPU_SHIFT) + 1;
  119         sc->sc_nirq = ((x & OPENPIC_FEATURE_LAST_IRQ_MASK) >>
  120             OPENPIC_FEATURE_LAST_IRQ_SHIFT) + 1;
  121 
  122         /*
  123          * PSIM seems to report 1 too many IRQs
  124          */
  125         if (sc->sc_psim)
  126                 sc->sc_nirq--;
  127 
  128         if (bootverbose)
  129                 device_printf(dev,
  130                     "Version %s, supports %d CPUs and %d irqs\n",
  131                     sc->sc_version, sc->sc_ncpu, sc->sc_nirq);
  132 
  133         /* disable all interrupts */
  134         for (irq = 0; irq < sc->sc_nirq; irq++)
  135                 openpic_write(sc, OPENPIC_SRC_VECTOR(irq), OPENPIC_IMASK);
  136 
  137         openpic_set_priority(sc, 0, 15);
  138 
  139         /* we don't need 8259 passthrough mode */
  140         x = openpic_read(sc, OPENPIC_CONFIG);
  141         x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
  142         openpic_write(sc, OPENPIC_CONFIG, x);
  143 
  144         /* send all interrupts to cpu 0 */
  145         for (irq = 0; irq < sc->sc_nirq; irq++)
  146                 openpic_write(sc, OPENPIC_IDEST(irq), 1 << 0);
  147 
  148         for (irq = 0; irq < sc->sc_nirq; irq++) {
  149                 x = irq;                /* irq == vector. */
  150                 x |= OPENPIC_IMASK;
  151                 x |= OPENPIC_POLARITY_POSITIVE;
  152                 x |= OPENPIC_SENSE_LEVEL;
  153                 x |= 8 << OPENPIC_PRIORITY_SHIFT;
  154                 openpic_write(sc, OPENPIC_SRC_VECTOR(irq), x);
  155         }
  156 
  157         /* XXX IPI */
  158         /* XXX set spurious intr vector */
  159 
  160         openpic_set_priority(sc, 0, 0);
  161 
  162         /* clear all pending interrupts */
  163         for (irq = 0; irq < sc->sc_nirq; irq++) {
  164                 (void)openpic_read(sc, OPENPIC_IACK(0));
  165                 openpic_write(sc, OPENPIC_EOI(0), 0);
  166         }
  167 
  168         powerpc_register_pic(dev);
  169 
  170         return (0);
  171 }
  172 
  173 /*
  174  * PIC I/F methods
  175  */
  176 
  177 void
  178 openpic_dispatch(device_t dev, struct trapframe *tf)
  179 {
  180         struct openpic_softc *sc;
  181         u_int vector;
  182 
  183         sc = device_get_softc(dev);
  184         while (1) {
  185                 vector = openpic_read(sc, OPENPIC_IACK(0));
  186                 vector &= OPENPIC_VECTOR_MASK;
  187                 if (vector == 255)
  188                         break;
  189                 powerpc_dispatch_intr(vector, tf);
  190         }
  191 }
  192 
  193 void
  194 openpic_enable(device_t dev, u_int irq, u_int vector)
  195 {
  196         struct openpic_softc *sc;
  197         uint32_t x;
  198 
  199         sc = device_get_softc(dev);
  200         x = openpic_read(sc, OPENPIC_SRC_VECTOR(irq));
  201         x &= ~(OPENPIC_IMASK | OPENPIC_VECTOR_MASK);
  202         x |= vector;
  203         openpic_write(sc, OPENPIC_SRC_VECTOR(irq), x);
  204 }
  205 
  206 void
  207 openpic_eoi(device_t dev, u_int irq __unused)
  208 {
  209         struct openpic_softc *sc;
  210 
  211         sc = device_get_softc(dev);
  212         openpic_write(sc, OPENPIC_EOI(0), 0);
  213 }
  214 
  215 void
  216 openpic_mask(device_t dev, u_int irq)
  217 {
  218         struct openpic_softc *sc;
  219         uint32_t x;
  220 
  221         sc = device_get_softc(dev);
  222         x = openpic_read(sc, OPENPIC_SRC_VECTOR(irq));
  223         x |= OPENPIC_IMASK;
  224         openpic_write(sc, OPENPIC_SRC_VECTOR(irq), x);
  225         openpic_write(sc, OPENPIC_EOI(0), 0);
  226 }
  227 
  228 void
  229 openpic_unmask(device_t dev, u_int irq)
  230 {
  231         struct openpic_softc *sc;
  232         uint32_t x;
  233 
  234         sc = device_get_softc(dev);
  235         x = openpic_read(sc, OPENPIC_SRC_VECTOR(irq));
  236         x &= ~OPENPIC_IMASK;
  237         openpic_write(sc, OPENPIC_SRC_VECTOR(irq), x);
  238 }

Cache object: 495db785a3cbecc133a47bab18a0df07


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.