1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_PCMU_IB_H 27 #define _SYS_PCMU_IB_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #include <sys/ddi_subrdefs.h> 36 37 typedef uint8_t pcmu_ib_ino_t; 38 typedef uint16_t pcmu_ib_mondo_t; 39 40 /* 41 * The following structure represents an interrupt entry for an INO. 42 */ 43 typedef struct ih { 44 dev_info_t *ih_dip; /* devinfo structure */ 45 uint32_t ih_inum; /* interrupt number for this device */ 46 uint_t ih_intr_state; /* Only used for fixed interrupts */ 47 uint_t (*ih_handler)(); /* interrupt handler */ 48 caddr_t ih_handler_arg1; /* interrupt handler argument #1 */ 49 caddr_t ih_handler_arg2; /* interrupt handler argument #2 */ 50 ddi_acc_handle_t ih_config_handle; /* config space reg map handle */ 51 struct ih *ih_next; /* next entry in list */ 52 } ih_t; 53 54 /* 55 * ino structure : one per CMU-CH ino with interrupt registered 56 */ 57 typedef struct pcmu_ib_ino_info { 58 struct pcmu_ib_ino_info *pino_next; 59 pcmu_ib_ino_t pino_ino; /* INO number - 8 bit */ 60 uint8_t pino_slot_no; /* PCI slot number 0-8 */ 61 uint16_t pino_ih_size; /* size of the pci intrspec list */ 62 ih_t *pino_ih_head; /* intr spec (part of ppd) list head */ 63 ih_t *pino_ih_tail; /* intr spec (part of ppd) list tail */ 64 ih_t *pino_ih_start; /* starting point in intr spec list */ 65 pcmu_ib_t *pino_ib_p; /* link back to interrupt block state */ 66 volatile uint64_t *pino_clr_reg; /* ino interrupt clear register */ 67 volatile uint64_t *pino_map_reg; /* ino interrupt mapping register */ 68 uint64_t pino_map_reg_save; /* = *pino_map_reg if saved */ 69 uint32_t pino_pil; /* PIL for this ino */ 70 volatile uint_t pino_unclaimed; /* number of unclaimed interrupts */ 71 clock_t pino_spurintr_begin; /* begin time of spurious intr series */ 72 int pino_established; /* ino has been associated with a cpu */ 73 uint32_t pino_cpuid; /* cpu that ino is targeting */ 74 int32_t pino_intr_weight; /* intr weight of devices sharing ino */ 75 } pcmu_ib_ino_info_t; 76 77 /* 78 * interrupt block soft state structure: 79 */ 80 struct pcmu_ib { 81 pcmu_t *pib_pcmu_p; /* link back to pci soft state */ 82 pcmu_ign_t pib_ign; /* interrupt group # */ 83 uintptr_t pib_obio_intr_map_regs; /* onboard intr map register */ 84 uintptr_t pib_obio_clear_intr_regs; /* onboard intr clear reg */ 85 volatile uint64_t *pib_upa_imr[2]; /* UPA expansion intr map register */ 86 uint64_t pib_upa_imr_state[2]; /* UPA intr map state */ /* RAGS */ 87 volatile uint64_t *pib_intr_retry_timer_reg; /* intr retry register */ 88 volatile uint64_t *pib_obio_intr_state_diag_reg; /* onboard intr st. */ 89 uint_t pib_max_ino; /* largest supported INO */ 90 pcmu_ib_ino_info_t *pib_ino_lst; /* ino link list */ 91 kmutex_t pib_ino_lst_mutex; /* mutex for ino link list */ 92 kmutex_t pib_intr_lock; /* lock for internal intr */ 93 }; 94 95 #define PCMU_MAX_INO 0x3f 96 #define PCMU_INO_BITS 6 /* INO#s are 6 bits long */ 97 98 /* 99 * Only used for fixed or legacy interrupts 100 */ 101 #define PCMU_INTR_STATE_DISABLE 0 /* disabled */ 102 #define PCMU_INTR_STATE_ENABLE 1 /* enabled */ 103 104 #define PCMU_IB_INTR_WAIT 1 /* wait for inter completion */ 105 #define PCMU_IB_INTR_NOWAIT 0 /* handling intr, no wait */ 106 107 #define PCMU_IB2CB(pib_p) ((pib_p)->pib_pcmu_p->pcmu_cb_p) 108 109 #define PCMU_IB_MONDO_TO_INO(mondo) ((pcmu_ib_ino_t)((mondo) & 0x3f)) 110 #define PCMU_IB_INO_INTR_ON(reg_p) *(reg_p) |= PCMU_INTR_MAP_REG_VALID 111 #define PCMU_IB_INO_INTR_OFF(reg_p) *(reg_p) &= ~PCMU_INTR_MAP_REG_VALID 112 #define PCMU_IB_INO_INTR_STATE_REG(pib_p, ino) \ 113 (pib_p->pib_obio_intr_state_diag_reg) 114 115 #define PCMU_IB_INO_INTR_PENDING(reg_p, ino) \ 116 (((*(reg_p) >> (((ino) & 0x1f) << 1)) & \ 117 PCMU_CLEAR_INTR_REG_MASK) == PCMU_CLEAR_INTR_REG_PENDING) 118 119 #define PCMU_IB_INO_INTR_CLEAR(reg_p) *(reg_p) = PCMU_CLEAR_INTR_REG_IDLE 120 #define PCMU_IB_INO_INTR_PEND(reg_p) *(reg_p) = PCMU_CLEAR_INTR_REG_PENDING 121 #define PCMU_IB_INO_INTR_ISON(imr) ((imr) >> 31) 122 123 #define PCMU_IB_IMR2MONDO(imr) ((imr) & \ 124 (PCMU_INTR_MAP_REG_IGN | PCMU_INTR_MAP_REG_INO)) 125 126 #define PCMU_IB_IS_OBIO_INO(ino) (ino & 0x20) 127 128 #define PCMU_IB_IGN_TO_MONDO(ign, ino) (((ign) << PCMU_INO_BITS) | (ino)) 129 #define PCMU_IB_INO_TO_MONDO(pib_p, ino) \ 130 PCMU_IB_IGN_TO_MONDO((pib_p)->pib_ign, ino) 131 132 133 extern int pcmu_pil[]; 134 135 /* 136 * Prototypes 137 */ 138 extern void pcmu_ib_create(pcmu_t *pcmu_p); 139 extern void pcmu_ib_destroy(pcmu_t *pcmu_p); 140 extern void pcmu_ib_configure(pcmu_ib_t *pib_p); 141 extern uint64_t ib_get_map_reg(pcmu_ib_mondo_t mondo, uint32_t cpu_id); 142 extern void pcmu_ib_intr_enable(pcmu_t *pcmu_p, pcmu_ib_ino_t ino); 143 extern void pcmu_ib_intr_disable(pcmu_ib_t *pib_p, pcmu_ib_ino_t ino, int wait); 144 extern void pcmu_ib_nintr_clear(pcmu_ib_t *pib_p, pcmu_ib_ino_t ino); 145 extern void pcmu_ib_suspend(pcmu_ib_t *pib_p); 146 extern void pcmu_ib_resume(pcmu_ib_t *pib_p); 147 extern pcmu_ib_ino_info_t *pcmu_ib_locate_ino(pcmu_ib_t *pib_p, 148 pcmu_ib_ino_t ino_num); 149 extern pcmu_ib_ino_info_t *pcmu_ib_new_ino(pcmu_ib_t *pib_p, 150 pcmu_ib_ino_t ino_num, ih_t *ih_p); 151 extern void pcmu_ib_delete_ino(pcmu_ib_t *pib_p, pcmu_ib_ino_info_t *ino_p); 152 extern void pcmu_ib_free_ino_all(pcmu_ib_t *pib_p); 153 extern int pcmu_ib_update_intr_state(pcmu_t *pcmu_p, dev_info_t *rdip, 154 ddi_intr_handle_impl_t *hdlp, uint_t new_intr_state); 155 extern void pcmu_ib_ino_add_intr(pcmu_t *pcmu_p, 156 pcmu_ib_ino_info_t *ino_p, ih_t *ih_p); 157 extern int pcmu_ib_ino_rem_intr(pcmu_t *pcmu_p, 158 pcmu_ib_ino_info_t *ino_p, ih_t *ih_p); 159 extern ih_t *pcmu_ib_ino_locate_intr(pcmu_ib_ino_info_t *ino_p, 160 dev_info_t *dip, uint32_t inum); 161 extern ih_t *pcmu_ib_alloc_ih(dev_info_t *dip, uint32_t inum, 162 uint_t (*int_handler)(caddr_t int_handler_arg1, caddr_t int_handler_arg2), 163 caddr_t int_handler_arg1, caddr_t int_handler_arg2); 164 extern void pcmu_ib_intr_dist_nintr(pcmu_ib_t *pib_p, pcmu_ib_ino_t ino, 165 volatile uint64_t *imr_p); 166 extern void pcmu_ib_intr_dist_all(void *arg, 167 int32_t max_weight, int32_t weight); 168 169 #ifdef __cplusplus 170 } 171 #endif 172 173 #endif /* _SYS_PCMU_IB_H */ 174