[BACK]Return to ipifuncs.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / hppa / hppa

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/arch/hppa/hppa/ipifuncs.c between version 1.2.4.1 and 1.2.4.2

version 1.2.4.1, 2012/04/05 16:16:01 version 1.2.4.2, 2012/04/17 00:06:26
Line 0 
Line 1 
   /*      $NetBSD$        */
   /*      $OpenBSD: ipi.c,v 1.4 2011/01/14 13:20:06 jsing Exp $   */
   
   /*
    * Copyright (c) 2010 Joel Sing <jsing@openbsd.org>
    *
    * Permission to use, copy, modify, and distribute this software for any
    * purpose with or without fee is hereby granted, provided that the above
    * copyright notice and this permission notice appear in all copies.
    *
    * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    */
   
   #include <sys/param.h>
   #include <sys/types.h>
   #include <sys/systm.h>
   #include <sys/mutex.h>
   #include <sys/device.h>
   #include <sys/atomic.h>
   #include <sys/xcall.h>
   
   #include <machine/cpu.h>
   #include <machine/cpufunc.h>
   #if 0
   #include <machine/fpu.h>
   #endif
   #include <machine/iomod.h>
   #include <machine/intr.h>
   #include <machine/mutex.h>
   #include <machine/reg.h>
   #include <machine/int_fmtio.h>
   
   #include <hppa/hppa/cpuvar.h>
   
   void hppa_ipi_nop(void);
   void hppa_ipi_halt(void);
   void hppa_ipi_xcall(void);
   
   void (*ipifunc[HPPA_NIPI])(void) =
   {
           hppa_ipi_nop,
           hppa_ipi_halt,
           hppa_ipi_xcall
   };
   
   const char *ipinames[HPPA_NIPI] = {
           "nop ipi",
           "halt ipi",
           "xcall ipi"
   };
   
   void
   hppa_ipi_init(struct cpu_info *ci)
   {
           struct cpu_softc *sc = ci->ci_softc;
           int i;
   
           evcnt_attach_dynamic(&sc->sc_evcnt_ipi, EVCNT_TYPE_INTR,
               NULL, device_xname(sc->sc_dev), "ipi");
   
           for (i = 0; i < HPPA_NIPI; i++) {
                   evcnt_attach_dynamic(&sc->sc_evcnt_which_ipi[i],
                       EVCNT_TYPE_INTR, NULL, device_xname(sc->sc_dev),
                       ipinames[i]);
           }
   }
   
   int
   hppa_ipi_intr(void *arg)
   {
           struct cpu_info *ci = curcpu();
           struct cpu_softc *sc = ci->ci_softc;
           u_long ipi_pending;
           int bit = 0;
   
           /* Handle an IPI. */
           ipi_pending = atomic_swap_ulong(&ci->ci_ipi, 0);
   
           KASSERT(ipi_pending);
   
           sc->sc_evcnt_ipi.ev_count++;
   
           while (ipi_pending) {
                   if (ipi_pending & (1L << bit)) {
                           sc->sc_evcnt_which_ipi[bit].ev_count++;
                           (*ipifunc[bit])();
                   }
                   ipi_pending &= ~(1L << bit);
                   bit++;
           }
   
           return 1;
   }
   
   int
   hppa_ipi_send(struct cpu_info *ci, u_long ipi)
   {
           struct iomod *cpu;
           KASSERT(ci->ci_flags & CPUF_RUNNING);
   
           atomic_or_ulong(&ci->ci_ipi, (1L << ipi));
   
           /* Send an IPI to the specified CPU by triggering EIR{1} (irq 30). */
           cpu = (struct iomod *)(ci->ci_hpa);
           cpu->io_eir = 1;
           membar_sync();
   
           return 0;
   }
   
   int
   hppa_ipi_broadcast(u_long ipi)
   {
           CPU_INFO_ITERATOR cii;
           struct cpu_info *ci;
           int count = 0;
   
           for (CPU_INFO_FOREACH(cii, ci)) {
                   if (ci != curcpu() && (ci->ci_flags & CPUF_RUNNING))
                           if (hppa_ipi_send(ci, ipi))
                                   count++;
           }
   
           return count;
   }
   
   void
   hppa_ipi_nop(void)
   {
   }
   
   void
   hppa_ipi_halt(void)
   {
           struct cpu_info *ci = curcpu();
   
           /* Turn off interrupts and halt CPU. */
   //      hppa_intr_disable();
           ci->ci_flags &= ~CPUF_RUNNING;
   
           for (;;)
                   ;
   }
   
   void
   hppa_ipi_xcall(void)
   {
   
           xc_ipi_handler();
   }
   
   void
   xc_send_ipi(struct cpu_info *ci)
   {
   
           KASSERT(kpreempt_disabled());
           KASSERT(curcpu() != ci);
   
           if (ci) {
                   /* Unicast: remote CPU. */
                   hppa_ipi_send(ci, HPPA_IPI_XCALL);
           } else {
                   /* Broadcast: all, but local CPU (caller will handle it). */
                   hppa_ipi_broadcast(HPPA_IPI_XCALL);
           }
   }

Legend:
Removed from v.1.2.4.1  
changed lines
  Added in v.1.2.4.2

CVSweb <webmaster@jp.NetBSD.org>