Home | History | Annotate | Line # | Download | only in pic
      1  1.20    andvar /*	$NetBSD: pic_openpic.c,v 1.20 2022/02/23 21:54:40 andvar Exp $ */
      2   1.2   garbled 
      3   1.2   garbled /*-
      4   1.2   garbled  * Copyright (c) 2007 Michael Lorenz
      5   1.2   garbled  * All rights reserved.
      6   1.2   garbled  *
      7   1.2   garbled  * Redistribution and use in source and binary forms, with or without
      8   1.2   garbled  * modification, are permitted provided that the following conditions
      9   1.2   garbled  * are met:
     10   1.2   garbled  * 1. Redistributions of source code must retain the above copyright
     11   1.2   garbled  *    notice, this list of conditions and the following disclaimer.
     12   1.2   garbled  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.2   garbled  *    notice, this list of conditions and the following disclaimer in the
     14   1.2   garbled  *    documentation and/or other materials provided with the distribution.
     15   1.2   garbled  *
     16   1.2   garbled  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17   1.2   garbled  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18   1.2   garbled  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19   1.2   garbled  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20   1.2   garbled  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21   1.2   garbled  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22   1.2   garbled  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23   1.2   garbled  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24   1.2   garbled  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25   1.2   garbled  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26   1.2   garbled  * POSSIBILITY OF SUCH DAMAGE.
     27   1.2   garbled  */
     28   1.2   garbled 
     29   1.2   garbled #include <sys/cdefs.h>
     30  1.20    andvar __KERNEL_RCSID(0, "$NetBSD: pic_openpic.c,v 1.20 2022/02/23 21:54:40 andvar Exp $");
     31  1.16       rin 
     32  1.16       rin #ifdef _KERNEL_OPT
     33  1.17       rin #include "opt_multiprocessor.h"
     34  1.17       rin #endif
     35  1.17       rin 
     36   1.2   garbled #include <sys/param.h>
     37   1.8      matt #include <sys/kmem.h>
     38   1.2   garbled #include <sys/kernel.h>
     39   1.2   garbled 
     40   1.2   garbled #include <uvm/uvm_extern.h>
     41   1.2   garbled 
     42   1.2   garbled #include <machine/pio.h>
     43   1.2   garbled #include <powerpc/openpic.h>
     44   1.2   garbled 
     45   1.6      matt #include <powerpc/pic/picvar.h>
     46   1.2   garbled 
     47   1.2   garbled static void opic_enable_irq(struct pic_ops *, int, int);
     48   1.2   garbled static void opic_disable_irq(struct pic_ops *, int);
     49   1.2   garbled static void opic_establish_irq(struct pic_ops*, int, int, int);
     50   1.2   garbled 
     51   1.2   garbled struct pic_ops *
     52   1.2   garbled setup_openpic(void *addr, int passthrough)
     53   1.2   garbled {
     54   1.4   garbled 	struct openpic_ops *opicops;
     55   1.2   garbled 	struct pic_ops *pic;
     56   1.2   garbled 	int irq;
     57   1.2   garbled 	u_int x;
     58   1.2   garbled 
     59  1.13  macallan 	openpic_base = addr;
     60   1.8      matt 	opicops = kmem_alloc(sizeof(*opicops), KM_SLEEP);
     61   1.4   garbled 	pic = &opicops->pic;
     62   1.2   garbled 
     63   1.2   garbled 	x = openpic_read(OPENPIC_FEATURE);
     64   1.4   garbled 	if (((x & 0x07ff0000) >> 16) == 0)
     65   1.4   garbled 		panic("setup_openpic() called on distributed openpic");
     66   1.4   garbled 
     67   1.2   garbled 	aprint_normal("OpenPIC Version 1.%d: "
     68   1.2   garbled 	    "Supports %d CPUs and %d interrupt sources.\n",
     69   1.2   garbled 	    x & 0xff, ((x & 0x1f00) >> 8) + 1, ((x & 0x07ff0000) >> 16) + 1);
     70   1.2   garbled 
     71  1.14  macallan 	pic->pic_numintrs = IPI_VECTOR + 1;
     72   1.2   garbled 	pic->pic_cookie = addr;
     73   1.2   garbled 	pic->pic_enable_irq = opic_enable_irq;
     74   1.2   garbled 	pic->pic_reenable_irq = opic_enable_irq;
     75   1.2   garbled 	pic->pic_disable_irq = opic_disable_irq;
     76   1.2   garbled 	pic->pic_get_irq = opic_get_irq;
     77   1.2   garbled 	pic->pic_ack_irq = opic_ack_irq;
     78   1.2   garbled 	pic->pic_establish_irq = opic_establish_irq;
     79   1.2   garbled 	pic->pic_finish_setup = opic_finish_setup;
     80   1.4   garbled 	opicops->isu = NULL;
     81   1.4   garbled 	opicops->nrofisus = 0; /* internal only */
     82   1.4   garbled 	opicops->flags = 0; /* no flags (yet) */
     83   1.4   garbled 	opicops->irq_per = NULL; /* internal ISU only */
     84   1.2   garbled 	strcpy(pic->pic_name, "openpic");
     85   1.2   garbled 	pic_add(pic);
     86   1.2   garbled 
     87   1.2   garbled 	/*
     88   1.2   garbled 	 * the following sequence should make the same effects as openpic
     89   1.2   garbled 	 * controller reset by writing a one at the self-clearing
     90   1.2   garbled 	 * OPENPIC_CONFIG_RESET bit.  Please check the document of your
     91   1.2   garbled 	 * OpenPIC compliant interrupt controller and see whether #else
     92   1.2   garbled 	 * portion can work as described.
     93   1.2   garbled 	 */
     94   1.2   garbled #if 1
     95   1.2   garbled 	openpic_set_priority(0, 15);
     96   1.2   garbled 
     97  1.14  macallan 	for (irq = 0; irq < (pic->pic_numintrs - 1); irq++) {
     98   1.2   garbled 		/* make sure to keep disabled */
     99   1.2   garbled 		openpic_write(OPENPIC_SRC_VECTOR(irq), OPENPIC_IMASK);
    100   1.2   garbled 		/* send all interrupts to CPU 0 */
    101   1.2   garbled 		openpic_write(OPENPIC_IDEST(irq), 1 << 0);
    102   1.2   garbled 	}
    103   1.2   garbled 
    104   1.2   garbled 	x = openpic_read(OPENPIC_CONFIG);
    105   1.2   garbled 	if (passthrough)
    106   1.2   garbled 		x &= ~OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
    107   1.2   garbled 	else
    108   1.2   garbled 		x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
    109   1.2   garbled 	openpic_write(OPENPIC_CONFIG, x);
    110   1.2   garbled 
    111   1.2   garbled 	openpic_write(OPENPIC_SPURIOUS_VECTOR, 0xff);
    112   1.2   garbled 
    113   1.2   garbled 	openpic_set_priority(0, 0);
    114   1.2   garbled 
    115  1.20    andvar 	/* clear all pending interrupts */
    116   1.2   garbled 	for (irq = 0; irq < pic->pic_numintrs; irq++) {
    117   1.2   garbled 		openpic_read_irq(0);
    118   1.2   garbled 		openpic_eoi(0);
    119   1.2   garbled 	}
    120   1.2   garbled #else
    121   1.2   garbled 	irq = 0;
    122   1.2   garbled 	openpic_write(OPENPIC_CONFIG, OPENPIC_CONFIG_RESET);
    123   1.2   garbled 	do {
    124   1.2   garbled 		x = openpic_read(OPENPIC_CONFIG);
    125   1.2   garbled 	} while (x & OPENPIC_CONFIG_RESET); /* S1C bit */
    126   1.2   garbled 	if (passthrough)
    127   1.2   garbled 		x &= ~OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
    128   1.2   garbled 	else
    129   1.2   garbled 		x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
    130   1.2   garbled 	openpic_write(OPENPIC_CONFIG, x);
    131   1.2   garbled 	openpic_set_priority(0, 0);
    132   1.2   garbled #endif
    133   1.2   garbled 
    134   1.2   garbled #if 0
    135   1.2   garbled 	printf("timebase freq=%d\n", openpic_read(0x10f0));
    136   1.2   garbled #endif
    137   1.2   garbled 	return pic;
    138   1.2   garbled }
    139   1.2   garbled 
    140   1.2   garbled static void
    141   1.2   garbled opic_establish_irq(struct pic_ops *pic, int irq, int type, int pri)
    142   1.2   garbled {
    143  1.15  riastrad 	int realpri = uimax(1, uimin(15, pri));
    144   1.2   garbled 	uint32_t x;
    145   1.2   garbled 
    146   1.2   garbled 	x = irq;
    147   1.2   garbled 	x |= OPENPIC_IMASK;
    148   1.7       phx 
    149  1.12  macallan 	if (type == IST_EDGE_RISING || type == IST_LEVEL_HIGH)
    150   1.7       phx 		x |= OPENPIC_POLARITY_POSITIVE;
    151   1.7       phx 	else
    152   1.7       phx 		x |= OPENPIC_POLARITY_NEGATIVE;
    153   1.7       phx 
    154   1.7       phx 	if (type == IST_EDGE_FALLING || type == IST_EDGE_RISING)
    155   1.7       phx 		x |= OPENPIC_SENSE_EDGE;
    156   1.7       phx 	else
    157   1.7       phx 		x |= OPENPIC_SENSE_LEVEL;
    158   1.7       phx 
    159   1.2   garbled 	x |= realpri << OPENPIC_PRIORITY_SHIFT;
    160  1.14  macallan #ifdef MULTIPROCESSOR
    161  1.14  macallan 	if (irq < IPI_VECTOR)
    162  1.14  macallan #endif
    163  1.14  macallan 		openpic_write(OPENPIC_SRC_VECTOR(irq), x);
    164   1.2   garbled 
    165   1.4   garbled 	aprint_debug("%s: setting IRQ %d to priority %d\n", __func__, irq,
    166   1.4   garbled 	    realpri);
    167   1.2   garbled }
    168   1.2   garbled 
    169   1.2   garbled static void
    170   1.2   garbled opic_enable_irq(struct pic_ops *pic, int irq, int type)
    171   1.2   garbled {
    172   1.2   garbled 	u_int x;
    173  1.14  macallan #ifdef MULTIPROCESSOR
    174  1.14  macallan 	if (irq == IPI_VECTOR) return;
    175  1.14  macallan #endif
    176   1.2   garbled 	x = openpic_read(OPENPIC_SRC_VECTOR(irq));
    177   1.2   garbled 	x &= ~OPENPIC_IMASK;
    178   1.2   garbled 	openpic_write(OPENPIC_SRC_VECTOR(irq), x);
    179   1.2   garbled }
    180   1.2   garbled 
    181   1.2   garbled static void
    182   1.2   garbled opic_disable_irq(struct pic_ops *pic, int irq)
    183   1.2   garbled {
    184   1.2   garbled 	u_int x;
    185   1.2   garbled 
    186  1.14  macallan #ifdef MULTIPROCESSOR
    187  1.14  macallan 	if (irq == IPI_VECTOR) return;
    188  1.14  macallan #endif
    189   1.2   garbled 	x = openpic_read(OPENPIC_SRC_VECTOR(irq));
    190   1.2   garbled 	x |= OPENPIC_IMASK;
    191   1.2   garbled 	openpic_write(OPENPIC_SRC_VECTOR(irq), x);
    192   1.2   garbled }
    193