Home | History | Annotate | Line # | Download | only in pic
pic_openpic.c revision 1.14.2.1
      1  1.14.2.1  christos /*	$NetBSD: pic_openpic.c,v 1.14.2.1 2019/06/10 22:06:39 christos 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.14.2.1  christos __KERNEL_RCSID(0, "$NetBSD: pic_openpic.c,v 1.14.2.1 2019/06/10 22:06:39 christos Exp $");
     31       1.2   garbled 
     32       1.2   garbled #include <sys/param.h>
     33       1.8      matt #include <sys/kmem.h>
     34       1.2   garbled #include <sys/kernel.h>
     35       1.2   garbled 
     36       1.2   garbled #include <uvm/uvm_extern.h>
     37       1.2   garbled 
     38       1.2   garbled #include <machine/pio.h>
     39       1.2   garbled #include <powerpc/openpic.h>
     40       1.2   garbled 
     41       1.6      matt #include <powerpc/pic/picvar.h>
     42       1.2   garbled 
     43       1.2   garbled #include "opt_interrupt.h"
     44       1.2   garbled 
     45       1.2   garbled static void opic_enable_irq(struct pic_ops *, int, int);
     46       1.2   garbled static void opic_disable_irq(struct pic_ops *, int);
     47       1.2   garbled static void opic_establish_irq(struct pic_ops*, int, int, int);
     48       1.2   garbled 
     49       1.2   garbled struct pic_ops *
     50       1.2   garbled setup_openpic(void *addr, int passthrough)
     51       1.2   garbled {
     52       1.4   garbled 	struct openpic_ops *opicops;
     53       1.2   garbled 	struct pic_ops *pic;
     54       1.2   garbled 	int irq;
     55       1.2   garbled 	u_int x;
     56       1.2   garbled 
     57      1.13  macallan 	openpic_base = addr;
     58       1.8      matt 	opicops = kmem_alloc(sizeof(*opicops), KM_SLEEP);
     59       1.4   garbled 	pic = &opicops->pic;
     60       1.2   garbled 
     61       1.2   garbled 	x = openpic_read(OPENPIC_FEATURE);
     62       1.4   garbled 	if (((x & 0x07ff0000) >> 16) == 0)
     63       1.4   garbled 		panic("setup_openpic() called on distributed openpic");
     64       1.4   garbled 
     65       1.2   garbled 	aprint_normal("OpenPIC Version 1.%d: "
     66       1.2   garbled 	    "Supports %d CPUs and %d interrupt sources.\n",
     67       1.2   garbled 	    x & 0xff, ((x & 0x1f00) >> 8) + 1, ((x & 0x07ff0000) >> 16) + 1);
     68       1.2   garbled 
     69      1.14  macallan 	pic->pic_numintrs = IPI_VECTOR + 1;
     70       1.2   garbled 	pic->pic_cookie = addr;
     71       1.2   garbled 	pic->pic_enable_irq = opic_enable_irq;
     72       1.2   garbled 	pic->pic_reenable_irq = opic_enable_irq;
     73       1.2   garbled 	pic->pic_disable_irq = opic_disable_irq;
     74       1.2   garbled 	pic->pic_get_irq = opic_get_irq;
     75       1.2   garbled 	pic->pic_ack_irq = opic_ack_irq;
     76       1.2   garbled 	pic->pic_establish_irq = opic_establish_irq;
     77       1.2   garbled 	pic->pic_finish_setup = opic_finish_setup;
     78       1.4   garbled 	opicops->isu = NULL;
     79       1.4   garbled 	opicops->nrofisus = 0; /* internal only */
     80       1.4   garbled 	opicops->flags = 0; /* no flags (yet) */
     81       1.4   garbled 	opicops->irq_per = NULL; /* internal ISU only */
     82       1.2   garbled 	strcpy(pic->pic_name, "openpic");
     83       1.2   garbled 	pic_add(pic);
     84       1.2   garbled 
     85       1.2   garbled 	/*
     86       1.2   garbled 	 * the following sequence should make the same effects as openpic
     87       1.2   garbled 	 * controller reset by writing a one at the self-clearing
     88       1.2   garbled 	 * OPENPIC_CONFIG_RESET bit.  Please check the document of your
     89       1.2   garbled 	 * OpenPIC compliant interrupt controller and see whether #else
     90       1.2   garbled 	 * portion can work as described.
     91       1.2   garbled 	 */
     92       1.2   garbled #if 1
     93       1.2   garbled 	openpic_set_priority(0, 15);
     94       1.2   garbled 
     95      1.14  macallan 	for (irq = 0; irq < (pic->pic_numintrs - 1); irq++) {
     96       1.2   garbled 		/* make sure to keep disabled */
     97       1.2   garbled 		openpic_write(OPENPIC_SRC_VECTOR(irq), OPENPIC_IMASK);
     98       1.2   garbled 		/* send all interrupts to CPU 0 */
     99       1.2   garbled 		openpic_write(OPENPIC_IDEST(irq), 1 << 0);
    100       1.2   garbled 	}
    101       1.2   garbled 
    102       1.2   garbled 	x = openpic_read(OPENPIC_CONFIG);
    103       1.2   garbled 	if (passthrough)
    104       1.2   garbled 		x &= ~OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
    105       1.2   garbled 	else
    106       1.2   garbled 		x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
    107       1.2   garbled 	openpic_write(OPENPIC_CONFIG, x);
    108       1.2   garbled 
    109       1.2   garbled 	openpic_write(OPENPIC_SPURIOUS_VECTOR, 0xff);
    110       1.2   garbled 
    111       1.2   garbled 	openpic_set_priority(0, 0);
    112       1.2   garbled 
    113       1.2   garbled 	/* clear all pending interrunts */
    114       1.2   garbled 	for (irq = 0; irq < pic->pic_numintrs; irq++) {
    115       1.2   garbled 		openpic_read_irq(0);
    116       1.2   garbled 		openpic_eoi(0);
    117       1.2   garbled 	}
    118       1.2   garbled #else
    119       1.2   garbled 	irq = 0;
    120       1.2   garbled 	openpic_write(OPENPIC_CONFIG, OPENPIC_CONFIG_RESET);
    121       1.2   garbled 	do {
    122       1.2   garbled 		x = openpic_read(OPENPIC_CONFIG);
    123       1.2   garbled 	} while (x & OPENPIC_CONFIG_RESET); /* S1C bit */
    124       1.2   garbled 	if (passthrough)
    125       1.2   garbled 		x &= ~OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
    126       1.2   garbled 	else
    127       1.2   garbled 		x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
    128       1.2   garbled 	openpic_write(OPENPIC_CONFIG, x);
    129       1.2   garbled 	openpic_set_priority(0, 0);
    130       1.2   garbled #endif
    131       1.2   garbled 
    132       1.2   garbled #if 0
    133       1.2   garbled 	printf("timebase freq=%d\n", openpic_read(0x10f0));
    134       1.2   garbled #endif
    135       1.2   garbled 	return pic;
    136       1.2   garbled }
    137       1.2   garbled 
    138       1.2   garbled static void
    139       1.2   garbled opic_establish_irq(struct pic_ops *pic, int irq, int type, int pri)
    140       1.2   garbled {
    141  1.14.2.1  christos 	int realpri = uimax(1, uimin(15, pri));
    142       1.2   garbled 	uint32_t x;
    143       1.2   garbled 
    144       1.2   garbled 	x = irq;
    145       1.2   garbled 	x |= OPENPIC_IMASK;
    146       1.7       phx 
    147      1.12  macallan 	if (type == IST_EDGE_RISING || type == IST_LEVEL_HIGH)
    148       1.7       phx 		x |= OPENPIC_POLARITY_POSITIVE;
    149       1.7       phx 	else
    150       1.7       phx 		x |= OPENPIC_POLARITY_NEGATIVE;
    151       1.7       phx 
    152       1.7       phx 	if (type == IST_EDGE_FALLING || type == IST_EDGE_RISING)
    153       1.7       phx 		x |= OPENPIC_SENSE_EDGE;
    154       1.7       phx 	else
    155       1.7       phx 		x |= OPENPIC_SENSE_LEVEL;
    156       1.7       phx 
    157       1.2   garbled 	x |= realpri << OPENPIC_PRIORITY_SHIFT;
    158      1.14  macallan #ifdef MULTIPROCESSOR
    159      1.14  macallan 	if (irq < IPI_VECTOR)
    160      1.14  macallan #endif
    161      1.14  macallan 		openpic_write(OPENPIC_SRC_VECTOR(irq), x);
    162       1.2   garbled 
    163       1.4   garbled 	aprint_debug("%s: setting IRQ %d to priority %d\n", __func__, irq,
    164       1.4   garbled 	    realpri);
    165       1.2   garbled }
    166       1.2   garbled 
    167       1.2   garbled static void
    168       1.2   garbled opic_enable_irq(struct pic_ops *pic, int irq, int type)
    169       1.2   garbled {
    170       1.2   garbled 	u_int x;
    171      1.14  macallan #ifdef MULTIPROCESSOR
    172      1.14  macallan 	if (irq == IPI_VECTOR) return;
    173      1.14  macallan #endif
    174       1.2   garbled 	x = openpic_read(OPENPIC_SRC_VECTOR(irq));
    175       1.2   garbled 	x &= ~OPENPIC_IMASK;
    176       1.2   garbled 	openpic_write(OPENPIC_SRC_VECTOR(irq), x);
    177       1.2   garbled }
    178       1.2   garbled 
    179       1.2   garbled static void
    180       1.2   garbled opic_disable_irq(struct pic_ops *pic, int irq)
    181       1.2   garbled {
    182       1.2   garbled 	u_int x;
    183       1.2   garbled 
    184      1.14  macallan #ifdef MULTIPROCESSOR
    185      1.14  macallan 	if (irq == IPI_VECTOR) return;
    186      1.14  macallan #endif
    187       1.2   garbled 	x = openpic_read(OPENPIC_SRC_VECTOR(irq));
    188       1.2   garbled 	x |= OPENPIC_IMASK;
    189       1.2   garbled 	openpic_write(OPENPIC_SRC_VECTOR(irq), x);
    190       1.2   garbled }
    191