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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_PCICMU_H 27 #define _SYS_PCICMU_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 #include <sys/pci.h> 37 #include <sys/pci_intr_lib.h> 38 #include <sys/pcicmu/pcmu_types.h> 39 #include <sys/pcicmu/pcmu_ib.h> 40 #include <sys/pcicmu/pcmu_cb.h> 41 #include <sys/pcicmu/pcmu_ecc.h> 42 #include <sys/pcicmu/pcmu_pbm.h> 43 #include <sys/pcicmu/pcmu_counters.h> 44 #include <sys/pcicmu/pcmu_util.h> 45 #include <sys/pcicmu/pcmu_err.h> 46 47 48 /* 49 * The following typedef is used to represent a 50 * 1275 "bus-range" property of a PCI Bus node. 51 */ 52 struct pcmu_bus_range { 53 uint32_t lo; 54 uint32_t hi; 55 }; 56 57 /* 58 * Structure to represent an entry in the 59 * "ranges" property of a device node. 60 */ 61 struct pcmu_ranges { 62 uint32_t child_high; 63 uint32_t child_mid; 64 uint32_t child_low; 65 uint32_t parent_high; 66 uint32_t parent_low; 67 uint32_t size_high; 68 uint32_t size_low; 69 }; 70 71 typedef enum { 72 PCMU_NEW, 73 PCMU_ATTACHED, 74 PCMU_DETACHED, 75 PCMU_SUSPENDED 76 } pcmu_state_t; 77 78 typedef enum { 79 PCMU_PBM_OBJ, 80 PCMU_ECC_OBJ, 81 PCMU_CB_OBJ 82 } pcmu_obj_t; 83 84 typedef enum { 85 PCMU_OBJ_INTR_ADD, 86 PCMU_OBJ_INTR_REMOVE 87 } pcmu_obj_op_t; 88 89 #define PCI_OPLCMU "pcicmu" 90 91 /* 92 * pcicmu soft state structure. 93 */ 94 struct pcicmu { 95 /* 96 * State flags and mutex: 97 */ 98 pcmu_state_t pcmu_state; 99 uint_t pcmu_soft_state; 100 uint_t pcmu_open_count; 101 kmutex_t pcmu_mutex; 102 103 /* 104 * Links to other state structures: 105 */ 106 dev_info_t *pcmu_dip; /* devinfo structure */ 107 pcmu_ib_t *pcmu_ib_p; /* interrupt block */ 108 pcmu_cb_t *pcmu_cb_p; /* control block */ 109 pcmu_pbm_t *pcmu_pcbm_p; /* PBM block */ 110 pcmu_ecc_t *pcmu_pecc_p; /* ECC error block */ 111 112 /* 113 * other state info: 114 */ 115 uint_t pcmu_id; /* Jupiter device id */ 116 uint32_t pcmu_rev; /* Bus bridge chip identification */ 117 118 /* 119 * pci device node properties: 120 */ 121 pcmu_bus_range_t pcmu_bus_range; /* "bus-range" */ 122 pcmu_ranges_t *pcmu_ranges; /* "ranges" data & length */ 123 int pcmu_ranges_length; 124 uint32_t *pcmu_inos; /* inos from "interrupts" prop */ 125 int pcmu_inos_len; /* "interrupts" length */ 126 int pcmu_numproxy; /* upa interrupt proxies */ 127 128 /* 129 * register mapping: 130 */ 131 caddr_t pcmu_address[4]; 132 ddi_acc_handle_t pcmu_ac[4]; 133 134 /* 135 * Performance counters kstat. 136 */ 137 pcmu_cntr_pa_t pcmu_uks_pa; 138 kstat_t *pcmu_uksp; /* ptr to upstream kstat */ 139 kmutex_t pcmu_err_mutex; /* per chip error handling mutex */ 140 141 /* Fault Management support */ 142 int pcmu_fm_cap; 143 ddi_iblock_cookie_t pcmu_fm_ibc; 144 }; 145 146 /* 147 * pcmu_soft_state values. 148 */ 149 #define PCMU_SOFT_STATE_OPEN 0x01 150 #define PCMU_SOFT_STATE_OPEN_EXCL 0x02 151 #define PCMU_SOFT_STATE_CLOSED 0x04 152 153 /* 154 * CMU-CH and PBM soft state macros: 155 */ 156 #define PCMU_AP_MINOR_NUM_TO_INSTANCE(x) ((x) >> 8) 157 158 #define get_pcmu_soft_state(i) \ 159 ((pcmu_t *)ddi_get_soft_state(per_pcmu_state, (i))) 160 161 #define alloc_pcmu_soft_state(i) \ 162 ddi_soft_state_zalloc(per_pcmu_state, (i)) 163 164 #define free_pcmu_soft_state(i) \ 165 ddi_soft_state_free(per_pcmu_state, (i)) 166 167 #define DEV_TO_SOFTSTATE(dev) ((pcmu_t *)ddi_get_soft_state(per_pcmu_state, \ 168 PCMU_AP_MINOR_NUM_TO_INSTANCE(getminor(dev)))) 169 170 #define PCMU_ATTACH_RETCODE(obj, op, err) \ 171 ((err) ? (obj) << 8 | (op) << 4 | (err) & 0xf : DDI_SUCCESS) 172 173 174 /* 175 * Performance counters information. 176 */ 177 #define PCMU_SHIFT_PIC0 8 178 #define PCMU_SHIFT_PIC1 0 179 180 /* 181 * CMU-CH-specific register offsets & bit field positions. 182 */ 183 184 /* 185 * Offsets of global registers: 186 */ 187 #define PCMU_CB_DEVICE_ID_REG_OFFSET 0x00000000 /* RAGS */ 188 #define PCMU_CB_CONTROL_STATUS_REG_OFFSET 0x00000010 189 190 /* 191 * CMU-CH performance counters offsets. 192 */ 193 #define PCMU_PERF_PCR_OFFSET 0x00000100 194 #define PCMU_PERF_PIC_OFFSET 0x00000108 195 196 /* 197 * Offsets of registers in the interrupt block: 198 */ 199 #define PCMU_IB_OBIO_INTR_MAP_REG_OFFSET 0x00001000 200 #define PCMU_IB_OBIO_CLEAR_INTR_REG_OFFSET 0x00001800 201 202 /* 203 * Offsets of registers in the PBM block: 204 */ 205 #define PCMU_PCI_PBM_REG_BASE 0x00002000 /* RAGS */ 206 #define PCMU_PCI_CTRL_REG_OFFSET 0x00000000 207 #define PCMU_PCI_ASYNC_FLT_STATUS_REG_OFFSET 0x00000010 208 #define PCMU_PCI_ASYNC_FLT_ADDR_REG_OFFSET 0x00000018 209 #define PCMU_PCI_DIAG_REG_OFFSET 0x00000020 210 211 /* 212 * CMU-CH control register bit definitions: 213 */ 214 #define PCMU_CB_CONTROL_STATUS_MODE 0x0000000000000001ull 215 #define PCMU_CB_CONTROL_STATUS_IMPL 0xf000000000000000ull 216 #define PCMU_CB_CONTROL_STATUS_IMPL_SHIFT 60 217 #define PCMU_CB_CONTROL_STATUS_VER 0x0f00000000000000ull 218 #define PCMU_CB_CONTROL_STATUS_VER_SHIFT 56 219 220 /* 221 * CMU-CH ECC UE AFSR bit definitions: 222 */ 223 #define PCMU_ECC_UE_AFSR_BYTEMASK 0x0000ffff00000000ull 224 #define PCMU_ECC_UE_AFSR_BYTEMASK_SHIFT 32 225 #define PCMU_ECC_UE_AFSR_DW_OFFSET 0x00000000e0000000ull 226 #define PCMU_ECC_UE_AFSR_DW_OFFSET_SHIFT 29 227 #define PCMU_ECC_UE_AFSR_ID 0x000000001f000000ull 228 #define PCMU_ECC_UE_AFSR_ID_SHIFT 24 229 #define PCMU_ECC_UE_AFSR_BLK 0x0000000000800000ull 230 231 /* 232 * CMU-CH pci control register bits: 233 */ 234 #define PCMU_PCI_CTRL_ARB_PARK 0x0000000000200000ull 235 #define PCMU_PCI_CTRL_WAKEUP_EN 0x0000000000000200ull 236 #define PCMU_PCI_CTRL_ERR_INT_EN 0x0000000000000100ull 237 #define PCMU_PCI_CTRL_ARB_EN_MASK 0x000000000000000full 238 239 /* 240 * CMU-CH PCI asynchronous fault status register bit definitions: 241 */ 242 #define PCMU_PCI_AFSR_PE_SHIFT 60 243 #define PCMU_PCI_AFSR_SE_SHIFT 56 244 #define PCMU_PCI_AFSR_E_MA 0x0000000000000008ull 245 #define PCMU_PCI_AFSR_E_TA 0x0000000000000004ull 246 #define PCMU_PCI_AFSR_E_RTRY 0x0000000000000002ull 247 #define PCMU_PCI_AFSR_E_PERR 0x0000000000000001ull 248 #define PCMU_PCI_AFSR_E_MASK 0x000000000000000full 249 #define PCMU_PCI_AFSR_BYTEMASK 0x0000ffff00000000ull 250 #define PCMU_PCI_AFSR_BYTEMASK_SHIFT 32 251 #define PCMU_PCI_AFSR_BLK 0x0000000080000000ull 252 #define PCMU_PCI_AFSR_MID 0x000000003e000000ull 253 #define PCMU_PCI_AFSR_MID_SHIFT 25 254 255 /* 256 * CMU-CH PCI diagnostic register bit definitions: 257 */ 258 #define PCMU_PCI_DIAG_DIS_DWSYNC 0x0000000000000010ull 259 260 #define PBM_AFSR_TO_PRIERR(afsr) \ 261 (afsr >> PCMU_PCI_AFSR_PE_SHIFT & PCMU_PCI_AFSR_E_MASK) 262 #define PBM_AFSR_TO_SECERR(afsr) \ 263 (afsr >> PCMU_PCI_AFSR_SE_SHIFT & PCMU_PCI_AFSR_E_MASK) 264 265 #define PCMU_ID_TO_IGN(pcmu_id) ((pcmu_ign_t)UPAID_TO_IGN(pcmu_id)) 266 267 268 /* 269 * Number of dispatch target entries. 270 */ 271 #define U2U_DATA_NUM 16 272 273 /* 274 * Offsets of registers in the Interrupt Dispatch Table: 275 */ 276 #define U2U_MODE_STATUS_REGISTER_OFFSET 0x00000000 277 #define U2U_PID_REGISTER_OFFSET 0x00000008 278 #define U2U_DATA_REGISTER_OFFSET 0x00000010 279 280 /* 281 * Mode Status register bit definitions: 282 */ 283 #define U2U_MS_IEV 0x00000040 /* bit-6: Interrupt Extension enable */ 284 285 /* 286 * Index number of U2U registers in OBP's "regs-property" of CMU-CH 287 */ 288 #define REGS_INDEX_OF_U2U 3 289 290 /* 291 * The following two difinitions are used to control target id 292 * for Interrupt dispatch data by software. 293 */ 294 typedef struct u2u_ittrans_id { 295 uint_t u2u_tgt_cpu_id; /* target CPU ID */ 296 uint_t u2u_rsv1; /* reserved */ 297 volatile uint64_t *u2u_ino_map_reg; /* u2u intr. map register */ 298 } u2u_ittrans_id_t; 299 300 typedef struct u2u_ittrans_data { 301 kmutex_t u2u_ittrans_lock; 302 uintptr_t u2u_regs_base; /* "reg" property */ 303 ddi_acc_handle_t u2u_acc; /* pointer to acc */ 304 uint_t u2u_port_id; /* "PID" register n U2U */ 305 uint_t u2u_board; /* "board#" property */ 306 u2u_ittrans_id_t u2u_ittrans_id[U2U_DATA_NUM]; 307 } u2u_ittrans_data_t; 308 309 /* 310 * Driver binding name for OPL DC system 311 */ 312 #define PCICMU_OPL_DC_BINDING_NAME "pci10cf,1390" 313 314 /* 315 * Offsets of registers in the interrupt block: 316 */ 317 318 #define PCMU_IB_UPA0_INTR_MAP_REG_OFFSET 0x6000 319 #define PCMU_IB_UPA1_INTR_MAP_REG_OFFSET 0x8000 320 #define PCMU_IB_SLOT_CLEAR_INTR_REG_OFFSET 0x1400 321 #define PCMU_IB_OBIO_INTR_STATE_DIAG_REG 0xA808 322 #define PCMU_IB_INTR_RETRY_TIMER_OFFSET 0x1A00 323 324 /* 325 * Offsets of registers in the ECC block: 326 */ 327 #define PCMU_ECC_CSR_OFFSET 0x20 328 #define PCMU_UE_AFSR_OFFSET 0x30 329 #define PCMU_UE_AFAR_OFFSET 0x38 330 331 /* 332 * CMU-CH control register bit definitions: 333 */ 334 #define PCMU_CB_CONTROL_STATUS_IGN 0x0007c00000000000ull 335 #define PCMU_CB_CONTROL_STATUS_IGN_SHIFT 46 336 #define PCMU_CB_CONTROL_STATUS_APCKEN 0x0000000000000008ull 337 #define PCMU_CB_CONTROL_STATUS_APERR 0x0000000000000004ull 338 #define PCMU_CB_CONTROL_STATUS_IAP 0x0000000000000002ull 339 340 /* 341 * CMU-CH interrupt mapping register bit definitions: 342 */ 343 #define PCMU_INTR_MAP_REG_VALID 0x0000000080000000ull 344 #define PCMU_INTR_MAP_REG_TID 0x000000007C000000ull 345 #define PCMU_INTR_MAP_REG_IGN 0x00000000000007C0ull 346 #define PCMU_INTR_MAP_REG_INO 0x000000000000003full 347 #define PCMU_INTR_MAP_REG_TID_SHIFT 26 348 #define PCMU_INTR_MAP_REG_IGN_SHIFT 6 349 350 /* 351 * CMU-CH clear interrupt register bit definitions: 352 */ 353 #define PCMU_CLEAR_INTR_REG_MASK 0x0000000000000003ull 354 #define PCMU_CLEAR_INTR_REG_IDLE 0x0000000000000000ull 355 #define PCMU_CLEAR_INTR_REG_RECEIVED 0x0000000000000001ull 356 #define PCMU_CLEAR_INTR_REG_RSVD 0x0000000000000002ull 357 #define PCMU_CLEAR_INTR_REG_PENDING 0x0000000000000003ull 358 359 /* 360 * CMU-CH ECC control register bit definitions: 361 */ 362 #define PCMU_ECC_CTRL_ECC_EN 0x8000000000000000ull 363 #define PCMU_ECC_CTRL_UE_INTEN 0x4000000000000000ull 364 365 /* 366 * CMU-CH ECC UE AFSR bit definitions: 367 */ 368 #define PCMU_ECC_UE_AFSR_PE_SHIFT 61 369 #define PCMU_ECC_UE_AFSR_SE_SHIFT 58 370 #define PCMU_ECC_UE_AFSR_E_MASK 0x0000000000000007ull 371 #define PCMU_ECC_UE_AFSR_E_PIO 0x0000000000000004ull 372 373 /* 374 * CMU-CH PCI diagnostic register bit definitions: 375 */ 376 #define PCMU_PCI_DIAG_DIS_RETRY 0x0000000000000040ull 377 #define PCMU_PCI_DIAG_DIS_INTSYNC 0x0000000000000020ull 378 379 380 #define NAMEINST(dip) ddi_driver_name(dip), ddi_get_instance(dip) 381 #define NAMEADDR(dip) ddi_node_name(dip), ddi_get_name_addr(dip) 382 383 384 /* 385 * CMU-CH Tunables 386 */ 387 extern uint32_t pcmu_spurintr_duration; /* spurious interupt duration */ 388 extern ushort_t pcmu_command_default; /* default command */ 389 extern uint_t ecc_error_intr_enable; /* ECC error intr */ 390 extern uint_t pcmu_ecc_afsr_retries; /* num ECC afsr retries */ 391 extern uint_t pcmu_intr_retry_intv; /* intr retry interval */ 392 extern uint_t pcmu_panic_on_fatal_errors; /* PANIC on fatal errors */ 393 extern uint_t pcmu_unclaimed_intr_max; /* Max unclaimed interrupts */ 394 extern hrtime_t pcmu_intrpend_timeout; /* intr pending timeout */ 395 396 397 extern void *per_pcmu_state; /* per-pbm soft state pointer */ 398 extern kmutex_t pcmu_global_mutex; /* attach/detach common struct lock */ 399 extern uint64_t pcmu_errtrig_pa; 400 401 402 /* 403 * Prototypes. 404 */ 405 extern void pcmu_post_uninit_child(pcmu_t *); 406 extern void pcmu_kstat_init(void); 407 extern void pcmu_kstat_fini(void); 408 extern void pcmu_add_upstream_kstat(pcmu_t *); 409 extern void pcmu_fix_ranges(pcmu_ranges_t *, int); 410 extern uint_t pcmu_pbm_disable_errors(pcmu_pbm_t *); 411 extern uint32_t ib_map_reg_get_cpu(volatile uint64_t); 412 extern uint64_t *ib_intr_map_reg_addr(pcmu_ib_t *, pcmu_ib_ino_t); 413 extern uint64_t *ib_clear_intr_reg_addr(pcmu_ib_t *, pcmu_ib_ino_t); 414 extern void pcmu_cb_setup(pcmu_t *); 415 extern void pcmu_cb_teardown(pcmu_t *); 416 extern int cb_register_intr(pcmu_t *); 417 extern void cb_enable_intr(pcmu_t *); 418 extern uint64_t cb_ino_to_map_pa(pcmu_cb_t *, pcmu_ib_ino_t); 419 extern uint64_t cb_ino_to_clr_pa(pcmu_cb_t *, pcmu_ib_ino_t); 420 extern int cb_remove_xintr(pcmu_t *, dev_info_t *, dev_info_t *, 421 pcmu_ib_ino_t, pcmu_ib_mondo_t); 422 extern uint32_t pcmu_intr_dist_cpuid(pcmu_ib_t *, pcmu_ib_ino_info_t *); 423 extern void pcmu_ecc_setup(pcmu_ecc_t *); 424 extern ushort_t pcmu_ecc_get_synd(uint64_t); 425 extern void pcmu_pbm_setup(pcmu_pbm_t *); 426 extern void pcmu_pbm_teardown(pcmu_pbm_t *); 427 extern uintptr_t pcmu_ib_setup(pcmu_ib_t *); 428 extern int pcmu_get_numproxy(dev_info_t *); 429 extern int pcmu_ecc_add_intr(pcmu_t *, int, pcmu_ecc_intr_info_t *); 430 extern void pcmu_ecc_rem_intr(pcmu_t *, int, pcmu_ecc_intr_info_t *); 431 extern int pcmu_pbm_err_handler(dev_info_t *, ddi_fm_error_t *, 432 const void *, int); 433 extern void pcmu_ecc_classify(uint64_t, pcmu_ecc_errstate_t *); 434 extern int pcmu_pbm_classify(pcmu_pbm_errstate_t *); 435 extern int pcmu_check_error(pcmu_t *); 436 extern void set_intr_mapping_reg(int, uint64_t *, int); 437 extern uint32_t pcmu_class_to_pil(dev_info_t *rdip); 438 extern int pcmu_add_intr(dev_info_t *dip, dev_info_t *rdip, 439 ddi_intr_handle_impl_t *hdlp); 440 extern int pcmu_remove_intr(dev_info_t *dip, dev_info_t *rdip, 441 ddi_intr_handle_impl_t *hdlp); 442 extern void pcmu_intr_teardown(pcmu_t *pcmu_p); 443 444 extern int u2u_translate_tgtid(pcmu_t *, uint_t, volatile uint64_t *); 445 extern void u2u_ittrans_cleanup(u2u_ittrans_data_t *, volatile uint64_t *); 446 void pcmu_err_create(pcmu_t *pcmu_p); 447 void pcmu_err_destroy(pcmu_t *pcmu_p); 448 void pcmu_pbm_ereport_post(dev_info_t *dip, uint64_t ena, 449 pcmu_pbm_errstate_t *pbm_err); 450 #ifdef __cplusplus 451 } 452 #endif 453 454 #endif /* _SYS_PCICMU_H */ 455