Annotation of sys/arch/alpha/pci/pci_kn300.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: pci_kn300.c,v 1.1 2007/03/16 21:22:27 robert Exp $ */
! 2: /* $NetBSD: pci_kn300.c,v 1.28 2005/12/11 12:16:17 christos Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1998 by Matthew Jacob
! 6: * NASA AMES Research Center.
! 7: * All rights reserved.
! 8: *
! 9: * Redistribution and use in source and binary forms, with or without
! 10: * modification, are permitted provided that the following conditions
! 11: * are met:
! 12: * 1. Redistributions of source code must retain the above copyright
! 13: * notice immediately at the beginning of the file, without modification,
! 14: * this list of conditions, and the following disclaimer.
! 15: * 2. Redistributions in binary form must reproduce the above copyright
! 16: * notice, this list of conditions and the following disclaimer in the
! 17: * documentation and/or other materials provided with the distribution.
! 18: * 3. The name of the author may not be used to endorse or promote products
! 19: * derived from this software without specific prior written permission.
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
! 25: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 31: * SUCH DAMAGE.
! 32: */
! 33:
! 34: #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
! 35: #include <sys/types.h>
! 36: #include <sys/param.h>
! 37: #include <sys/time.h>
! 38: #include <sys/systm.h>
! 39: #include <sys/errno.h>
! 40: #include <sys/malloc.h>
! 41: #include <sys/device.h>
! 42: #include <sys/syslog.h>
! 43:
! 44: #include <uvm/uvm_extern.h>
! 45:
! 46: #include <machine/autoconf.h>
! 47:
! 48: #include <dev/pci/pcireg.h>
! 49: #include <dev/pci/pcivar.h>
! 50:
! 51: #include <alpha/mcbus/mcbusvar.h>
! 52: #include <alpha/mcbus/mcbusreg.h>
! 53: #include <alpha/pci/mcpciareg.h>
! 54: #include <alpha/pci/mcpciavar.h>
! 55: #include <alpha/pci/pci_kn300.h>
! 56:
! 57: #include "sio.h"
! 58: #if NSIO > 0 || NPCEB > 0
! 59: #include <alpha/pci/siovar.h>
! 60: #endif
! 61:
! 62: int dec_kn300_intr_map (void *, pcitag_t, int, int, pci_intr_handle_t *);
! 63:
! 64: const char *dec_kn300_intr_string (void *, pci_intr_handle_t);
! 65: void *dec_kn300_intr_establish (void *, pci_intr_handle_t,
! 66: int, int (*func)(void *), void *, char *);
! 67: void dec_kn300_intr_disestablish (void *, void *);
! 68:
! 69: #define KN300_PCEB_IRQ 16
! 70: #define NPIN 4
! 71:
! 72: #define NIRQ (MAX_MC_BUS * MCPCIA_PER_MCBUS * MCPCIA_MAXSLOT * NPIN)
! 73: static int savirqs[NIRQ];
! 74:
! 75: static struct alpha_shared_intr *kn300_pci_intr;
! 76:
! 77: static struct mcpcia_config *mcpcia_eisaccp = NULL;
! 78:
! 79: void kn300_iointr (void *, unsigned long);
! 80: void kn300_enable_intr (struct mcpcia_config *, int);
! 81: void kn300_disable_intr (struct mcpcia_config *, int);
! 82:
! 83: void
! 84: pci_kn300_pickintr(ccp, first)
! 85: struct mcpcia_config *ccp;
! 86: int first;
! 87: {
! 88: pci_chipset_tag_t pc = &ccp->cc_pc;
! 89:
! 90: if (first) {
! 91: int g;
! 92:
! 93: kn300_pci_intr = alpha_shared_intr_alloc(NIRQ);
! 94: for (g = 0; g < NIRQ; g++) {
! 95: alpha_shared_intr_set_maxstrays(kn300_pci_intr, g, 25);
! 96: savirqs[g] = (char) -1;
! 97: }
! 98: }
! 99:
! 100: pc->pc_intr_v = ccp;
! 101: pc->pc_intr_map = dec_kn300_intr_map;
! 102: pc->pc_intr_string = dec_kn300_intr_string;
! 103: pc->pc_intr_establish = dec_kn300_intr_establish;
! 104: pc->pc_intr_disestablish = dec_kn300_intr_disestablish;
! 105:
! 106: /* Not supported on KN300. */
! 107: pc->pc_pciide_compat_intr_establish = NULL;
! 108:
! 109: if (EISA_PRESENT(REGVAL(MCPCIA_PCI_REV(ccp)))) {
! 110: mcpcia_eisaccp = ccp;
! 111: #if NSIO > 0 || NPCEB > 0
! 112: sio_intr_setup(pc, &ccp->cc_iot);
! 113: kn300_enable_intr(ccp, KN300_PCEB_IRQ);
! 114: #endif
! 115: }
! 116: }
! 117:
! 118: int
! 119: dec_kn300_intr_map(ccv, bustag, buspin, line, ihp)
! 120: void *ccv;
! 121: pcitag_t bustag;
! 122: int buspin, line;
! 123: pci_intr_handle_t *ihp;
! 124: {
! 125: struct mcpcia_config *ccp = ccv;
! 126: pci_chipset_tag_t pc = &ccp->cc_pc;
! 127: int device;
! 128: int mcpcia_irq;
! 129:
! 130: if (buspin == 0) {
! 131: /* No IRQ used. */
! 132: return 1;
! 133: }
! 134: if (buspin > 4 || buspin < 0) {
! 135: printf("dec_kn300_intr_map: bad interrupt pin %d\n", buspin);
! 136: return 1;
! 137: }
! 138:
! 139: pci_decompose_tag(pc, bustag, NULL, &device, NULL);
! 140:
! 141: /*
! 142: * On MID 5 device 1 is the internal NCR 53c810.
! 143: */
! 144: if (ccp->cc_mid == 5 && device == 1) {
! 145: mcpcia_irq = 16;
! 146: } else if (device >= 2 && device <= 5) {
! 147: mcpcia_irq = (device - 2) * 4 + buspin - 1;
! 148: } else {
! 149: printf("dec_kn300_intr_map: weird device number %d\n", device);
! 150: return(1);
! 151: }
! 152:
! 153: /*
! 154: * handle layout:
! 155: *
! 156: * Determine kn300 IRQ (encoded in SCB vector):
! 157: * bits 0..1 buspin-1
! 158: * bits 2..4 PCI Slot (0..7- yes, some don't exist)
! 159: * bits 5..7 MID-4
! 160: * bits 8..10 7-GID
! 161: *
! 162: * Software only:
! 163: * bits 11-15 MCPCIA IRQ
! 164: */
! 165: *ihp = (pci_intr_handle_t)
! 166: (buspin - 1 ) |
! 167: ((device & 0x7) << 2) |
! 168: ((ccp->cc_mid - 4) << 5) |
! 169: ((7 - ccp->cc_gid) << 8) |
! 170: (mcpcia_irq << 11);
! 171: return (0);
! 172: }
! 173:
! 174: const char *
! 175: dec_kn300_intr_string(ccv, ih)
! 176: void *ccv;
! 177: pci_intr_handle_t ih;
! 178: {
! 179: static char irqstr[64];
! 180: int irq;
! 181:
! 182: irq = ih & 0x3ff;
! 183: if (irq > NIRQ)
! 184: panic("dec_kn300_intr_string: bogus kn300 IRQ 0x%x", irq);
! 185:
! 186: snprintf(irqstr, sizeof irqstr, "kn300 irq %ld", irq);
! 187:
! 188: return (irqstr);
! 189: }
! 190:
! 191: void *
! 192: dec_kn300_intr_establish(ccv, ih, level, func, arg, name)
! 193: void *ccv, *arg;
! 194: pci_intr_handle_t ih;
! 195: int level;
! 196: int (*func) (void *);
! 197: char *name;
! 198: {
! 199: struct mcpcia_config *ccp = ccv;
! 200: void *cookie;
! 201: int irq;
! 202:
! 203: irq = ih & 0x3ff;
! 204: if (irq > NIRQ)
! 205: panic("dec_kn300_intr_establish: bogus kn300 IRQ 0x%x", irq);
! 206:
! 207: cookie = alpha_shared_intr_establish(kn300_pci_intr, irq, IST_LEVEL,
! 208: level, func, arg, "kn300 irq");
! 209:
! 210: if (cookie != NULL &&
! 211: alpha_shared_intr_firstactive(kn300_pci_intr, irq)) {
! 212: scb_set(MCPCIA_VEC_PCI + SCB_IDXTOVEC(irq),
! 213: kn300_iointr, NULL);
! 214: alpha_shared_intr_set_private(kn300_pci_intr, irq, ccp);
! 215: savirqs[irq] = (ih >> 11) & 0x1f;
! 216: kn300_enable_intr(ccp, savirqs[irq]);
! 217: alpha_mb();
! 218: }
! 219: return (cookie);
! 220: }
! 221:
! 222: void
! 223: dec_kn300_intr_disestablish(ccv, cookie)
! 224: void *ccv, *cookie;
! 225: {
! 226: panic("dec_kn300_intr_disestablish not implemented");
! 227: }
! 228:
! 229: void
! 230: kn300_iointr(arg, vec)
! 231: void *arg;
! 232: unsigned long vec;
! 233: {
! 234: struct mcpcia_softc *mcp;
! 235: u_long irq;
! 236:
! 237: irq = SCB_VECTOIDX(vec - MCPCIA_VEC_PCI);
! 238:
! 239: if (alpha_shared_intr_dispatch(kn300_pci_intr, irq)) {
! 240: /*
! 241: * Any claim of an interrupt at this level is a hint to
! 242: * reset the stray interrupt count- elsewise a slow leak
! 243: * over time will cause this level to be shutdown.
! 244: */
! 245: alpha_shared_intr_reset_strays(kn300_pci_intr, irq);
! 246: return;
! 247: }
! 248:
! 249: /*
! 250: * If we haven't finished configuring yet, or there is no mcp
! 251: * registered for this level yet, just return.
! 252: */
! 253: mcp = alpha_shared_intr_get_private(kn300_pci_intr, irq);
! 254: if (mcp == NULL || mcp->mcpcia_cc == NULL)
! 255: return;
! 256:
! 257: /*
! 258: * We're getting an interrupt for a device we haven't enabled.
! 259: * We had better not try and use -1 to find the right bit to disable.
! 260: */
! 261: if (savirqs[irq] == -1) {
! 262: printf("kn300_iointr: stray interrupt vector 0x%lx\n", vec);
! 263: return;
! 264: }
! 265:
! 266: /*
! 267: * Stray interrupt; disable the IRQ on the appropriate MCPCIA
! 268: * if we've reached the limit.
! 269: */
! 270: alpha_shared_intr_stray(kn300_pci_intr, irq, "kn300 irq");
! 271: if (ALPHA_SHARED_INTR_DISABLE(kn300_pci_intr, irq) == 0)
! 272: return;
! 273: kn300_disable_intr(mcp->mcpcia_cc, savirqs[irq]);
! 274: }
! 275:
! 276: void
! 277: kn300_enable_intr(ccp, irq)
! 278: struct mcpcia_config *ccp;
! 279: int irq;
! 280: {
! 281: alpha_mb();
! 282: REGVAL(MCPCIA_INT_MASK0(ccp)) |= (1 << irq);
! 283: alpha_mb();
! 284: }
! 285:
! 286: void
! 287: kn300_disable_intr(ccp, irq)
! 288: struct mcpcia_config *ccp;
! 289: int irq;
! 290: {
! 291: alpha_mb();
! 292: REGVAL(MCPCIA_INT_MASK0(ccp)) &= ~(1 << irq);
! 293: alpha_mb();
! 294: }
CVSweb