Annotation of sys/arch/alpha/pci/pci_kn20aa.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: pci_kn20aa.c,v 1.22 2006/06/15 20:08:29 brad Exp $ */
! 2: /* $NetBSD: pci_kn20aa.c,v 1.21 1996/11/17 02:05:27 cgd Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1995, 1996 Carnegie-Mellon University.
! 6: * All rights reserved.
! 7: *
! 8: * Author: Chris G. Demetriou
! 9: *
! 10: * Permission to use, copy, modify and distribute this software and
! 11: * its documentation is hereby granted, provided that both the copyright
! 12: * notice and this permission notice appear in all copies of the
! 13: * software, derivative works or modified versions, and any portions
! 14: * thereof, and that both notices appear in supporting documentation.
! 15: *
! 16: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
! 17: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
! 18: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
! 19: *
! 20: * Carnegie Mellon requests users of this software to return to
! 21: *
! 22: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
! 23: * School of Computer Science
! 24: * Carnegie Mellon University
! 25: * Pittsburgh PA 15213-3890
! 26: *
! 27: * any improvements or extensions that they make and grant Carnegie the
! 28: * rights to redistribute these changes.
! 29: */
! 30:
! 31: #include <sys/types.h>
! 32: #include <sys/param.h>
! 33: #include <sys/time.h>
! 34: #include <sys/systm.h>
! 35: #include <sys/errno.h>
! 36: #include <sys/malloc.h>
! 37: #include <sys/device.h>
! 38: #include <sys/syslog.h>
! 39:
! 40: #include <uvm/uvm_extern.h>
! 41:
! 42: #include <machine/autoconf.h>
! 43:
! 44: #include <dev/pci/pcireg.h>
! 45: #include <dev/pci/pcivar.h>
! 46:
! 47: #include <alpha/pci/ciareg.h>
! 48: #include <alpha/pci/ciavar.h>
! 49:
! 50: #include <alpha/pci/pci_kn20aa.h>
! 51:
! 52: #include "sio.h"
! 53: #if NSIO
! 54: #include <alpha/pci/siovar.h>
! 55: #endif
! 56:
! 57: int dec_kn20aa_intr_map(void *, pcitag_t, int, int,
! 58: pci_intr_handle_t *);
! 59: const char *dec_kn20aa_intr_string(void *, pci_intr_handle_t);
! 60: int dec_kn20aa_intr_line(void *, pci_intr_handle_t);
! 61: void *dec_kn20aa_intr_establish(void *, pci_intr_handle_t,
! 62: int, int (*func)(void *), void *, char *);
! 63: void dec_kn20aa_intr_disestablish(void *, void *);
! 64:
! 65: #define KN20AA_PCEB_IRQ 31
! 66: #define KN20AA_MAX_IRQ 32
! 67: #define PCI_STRAY_MAX 5
! 68:
! 69: struct alpha_shared_intr *kn20aa_pci_intr;
! 70: struct evcount kn20aa_intr_count;
! 71:
! 72: void kn20aa_iointr(void *arg, unsigned long vec);
! 73: void kn20aa_enable_intr(int irq);
! 74: void kn20aa_disable_intr(int irq);
! 75:
! 76: void
! 77: pci_kn20aa_pickintr(ccp)
! 78: struct cia_config *ccp;
! 79: {
! 80: int i;
! 81: bus_space_tag_t iot = &ccp->cc_iot;
! 82: pci_chipset_tag_t pc = &ccp->cc_pc;
! 83:
! 84: pc->pc_intr_v = ccp;
! 85: pc->pc_intr_map = dec_kn20aa_intr_map;
! 86: pc->pc_intr_string = dec_kn20aa_intr_string;
! 87: pc->pc_intr_line = dec_kn20aa_intr_line;
! 88: pc->pc_intr_establish = dec_kn20aa_intr_establish;
! 89: pc->pc_intr_disestablish = dec_kn20aa_intr_disestablish;
! 90:
! 91: /* Not supported on KN20AA. */
! 92: pc->pc_pciide_compat_intr_establish = NULL;
! 93: pc->pc_pciide_compat_intr_disestablish = NULL;
! 94:
! 95: kn20aa_pci_intr = alpha_shared_intr_alloc(KN20AA_MAX_IRQ);
! 96: for (i = 0; i < KN20AA_MAX_IRQ; i++)
! 97: alpha_shared_intr_set_maxstrays(kn20aa_pci_intr, i,
! 98: PCI_STRAY_MAX);
! 99:
! 100: #if NSIO
! 101: sio_intr_setup(pc, iot);
! 102: kn20aa_enable_intr(KN20AA_PCEB_IRQ);
! 103: #endif
! 104: }
! 105:
! 106: int
! 107: dec_kn20aa_intr_map(ccv, bustag, buspin, line, ihp)
! 108: void *ccv;
! 109: pcitag_t bustag;
! 110: int buspin, line;
! 111: pci_intr_handle_t *ihp;
! 112: {
! 113: struct cia_config *ccp = ccv;
! 114: pci_chipset_tag_t pc = &ccp->cc_pc;
! 115: int device;
! 116: int kn20aa_irq;
! 117:
! 118: if (buspin == 0) {
! 119: /* No IRQ used. */
! 120: return 1;
! 121: }
! 122: if (buspin > 4) {
! 123: printf("pci_map_int: bad interrupt pin %d\n", buspin);
! 124: return 1;
! 125: }
! 126:
! 127: /*
! 128: * Slot->interrupt translation. Appears to work, though it
! 129: * may not hold up forever.
! 130: *
! 131: * The DEC engineers who did this hardware obviously engaged
! 132: * in random drug testing.
! 133: */
! 134: pci_decompose_tag(pc, bustag, NULL, &device, NULL);
! 135: switch (device) {
! 136: case 11:
! 137: case 12:
! 138: kn20aa_irq = ((device - 11) + 0) * 4;
! 139: break;
! 140:
! 141: case 7:
! 142: kn20aa_irq = 8;
! 143: break;
! 144:
! 145: case 9:
! 146: kn20aa_irq = 12;
! 147: break;
! 148:
! 149: case 6: /* 21040 on AlphaStation 500 */
! 150: kn20aa_irq = 13;
! 151: break;
! 152:
! 153: case 8:
! 154: kn20aa_irq = 16;
! 155: break;
! 156:
! 157: default:
! 158: printf("dec_kn20aa_intr_map: weird device number %d\n",
! 159: device);
! 160: return 1;
! 161: }
! 162:
! 163: kn20aa_irq += buspin - 1;
! 164: if (kn20aa_irq > KN20AA_MAX_IRQ)
! 165: panic("pci_kn20aa_map_int: kn20aa_irq too large (%d)",
! 166: kn20aa_irq);
! 167:
! 168: *ihp = kn20aa_irq;
! 169: return (0);
! 170: }
! 171:
! 172: const char *
! 173: dec_kn20aa_intr_string(ccv, ih)
! 174: void *ccv;
! 175: pci_intr_handle_t ih;
! 176: {
! 177: static char irqstr[15]; /* 11 + 2 + NULL + sanity */
! 178:
! 179: if (ih > KN20AA_MAX_IRQ)
! 180: panic("dec_kn20aa_intr_string: bogus kn20aa IRQ 0x%x", ih);
! 181:
! 182: snprintf(irqstr, sizeof irqstr, "kn20aa irq %ld", ih);
! 183: return (irqstr);
! 184: }
! 185:
! 186: int
! 187: dec_kn20aa_intr_line(ccv, ih)
! 188: void *ccv;
! 189: pci_intr_handle_t ih;
! 190: {
! 191: return (ih);
! 192: }
! 193:
! 194: void *
! 195: dec_kn20aa_intr_establish(ccv, ih, level, func, arg, name)
! 196: void *ccv, *arg;
! 197: pci_intr_handle_t ih;
! 198: int level;
! 199: int (*func)(void *);
! 200: char *name;
! 201: {
! 202: void *cookie;
! 203:
! 204: if (ih > KN20AA_MAX_IRQ)
! 205: panic("dec_kn20aa_intr_establish: bogus kn20aa IRQ 0x%x",
! 206: ih);
! 207:
! 208: cookie = alpha_shared_intr_establish(kn20aa_pci_intr, ih, IST_LEVEL,
! 209: level, func, arg, name);
! 210:
! 211: if (cookie != NULL &&
! 212: alpha_shared_intr_firstactive(kn20aa_pci_intr, ih)) {
! 213: scb_set(0x900 + SCB_IDXTOVEC(ih), kn20aa_iointr, NULL);
! 214: kn20aa_enable_intr(ih);
! 215: }
! 216: return (cookie);
! 217: }
! 218:
! 219: void
! 220: dec_kn20aa_intr_disestablish(ccv, cookie)
! 221: void *ccv, *cookie;
! 222: {
! 223: struct alpha_shared_intrhand *ih = cookie;
! 224: unsigned int irq = ih->ih_num;
! 225: int s;
! 226:
! 227: s = splhigh();
! 228:
! 229: alpha_shared_intr_disestablish(kn20aa_pci_intr, cookie,
! 230: "kn20aa irq");
! 231: if (alpha_shared_intr_isactive(kn20aa_pci_intr, irq) == 0) {
! 232: kn20aa_disable_intr(irq);
! 233: alpha_shared_intr_set_dfltsharetype(kn20aa_pci_intr, irq,
! 234: IST_NONE);
! 235: scb_free(0x900 + SCB_IDXTOVEC(irq));
! 236: }
! 237: splx(s);
! 238: }
! 239:
! 240: void
! 241: kn20aa_iointr(arg, vec)
! 242: void *arg;
! 243: unsigned long vec;
! 244: {
! 245: int irq;
! 246:
! 247: irq = SCB_VECTOIDX(vec - 0x900);
! 248:
! 249: if (!alpha_shared_intr_dispatch(kn20aa_pci_intr, irq)) {
! 250: alpha_shared_intr_stray(kn20aa_pci_intr, irq,
! 251: "kn20aa irq");
! 252: if (ALPHA_SHARED_INTR_DISABLE(kn20aa_pci_intr, irq))
! 253: kn20aa_disable_intr(irq);
! 254: } else
! 255: alpha_shared_intr_reset_strays(kn20aa_pci_intr, irq);
! 256: }
! 257:
! 258: void
! 259: kn20aa_enable_intr(irq)
! 260: int irq;
! 261: {
! 262:
! 263: /*
! 264: * From disassembling small bits of the OSF/1 kernel:
! 265: * the following appears to enable a given interrupt request.
! 266: * "blech." I'd give valuable body parts for better docs or
! 267: * for a good decompiler.
! 268: */
! 269: alpha_mb();
! 270: REGVAL(0x8780000000L + 0x40L) |= (1 << irq); /* XXX */
! 271: alpha_mb();
! 272: }
! 273:
! 274: void
! 275: kn20aa_disable_intr(irq)
! 276: int irq;
! 277: {
! 278:
! 279: alpha_mb();
! 280: REGVAL(0x8780000000L + 0x40L) &= ~(1 << irq); /* XXX */
! 281: alpha_mb();
! 282: }
CVSweb