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.
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.
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]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
29 #pragma ident "%Z%%M% %I% %E% SMI"
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>
49 * The following typedef is used to represent a
50 * 1275 "bus-range" property of a PCI Bus node.
52 struct pcmu_bus_range
{
58 * Structure to represent an entry in the
59 * "ranges" property of a device node.
89 #define PCI_OPLCMU "pcicmu"
92 * pcicmu soft state structure.
96 * State flags and mutex:
98 pcmu_state_t pcmu_state
;
99 uint_t pcmu_soft_state
;
100 uint_t pcmu_open_count
;
104 * Links to other state structures:
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 */
115 uint_t pcmu_id
; /* Jupiter device id */
116 uint32_t pcmu_rev
; /* Bus bridge chip identification */
119 * pci device node properties:
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 */
131 caddr_t pcmu_address
[4];
132 ddi_acc_handle_t pcmu_ac
[4];
135 * Performance counters kstat.
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 */
141 /* Fault Management support */
143 ddi_iblock_cookie_t pcmu_fm_ibc
;
147 * pcmu_soft_state values.
149 #define PCMU_SOFT_STATE_OPEN 0x01
150 #define PCMU_SOFT_STATE_OPEN_EXCL 0x02
151 #define PCMU_SOFT_STATE_CLOSED 0x04
154 * CMU-CH and PBM soft state macros:
156 #define PCMU_AP_MINOR_NUM_TO_INSTANCE(x) ((x) >> 8)
158 #define get_pcmu_soft_state(i) \
159 ((pcmu_t *)ddi_get_soft_state(per_pcmu_state, (i)))
161 #define alloc_pcmu_soft_state(i) \
162 ddi_soft_state_zalloc(per_pcmu_state, (i))
164 #define free_pcmu_soft_state(i) \
165 ddi_soft_state_free(per_pcmu_state, (i))
167 #define DEV_TO_SOFTSTATE(dev) ((pcmu_t *)ddi_get_soft_state(per_pcmu_state, \
168 PCMU_AP_MINOR_NUM_TO_INSTANCE(getminor(dev))))
170 #define PCMU_ATTACH_RETCODE(obj, op, err) \
171 ((err) ? (obj) << 8 | (op) << 4 | (err) & 0xf : DDI_SUCCESS)
175 * Performance counters information.
177 #define PCMU_SHIFT_PIC0 8
178 #define PCMU_SHIFT_PIC1 0
181 * CMU-CH-specific register offsets & bit field positions.
185 * Offsets of global registers:
187 #define PCMU_CB_DEVICE_ID_REG_OFFSET 0x00000000 /* RAGS */
188 #define PCMU_CB_CONTROL_STATUS_REG_OFFSET 0x00000010
191 * CMU-CH performance counters offsets.
193 #define PCMU_PERF_PCR_OFFSET 0x00000100
194 #define PCMU_PERF_PIC_OFFSET 0x00000108
197 * Offsets of registers in the interrupt block:
199 #define PCMU_IB_OBIO_INTR_MAP_REG_OFFSET 0x00001000
200 #define PCMU_IB_OBIO_CLEAR_INTR_REG_OFFSET 0x00001800
203 * Offsets of registers in the PBM block:
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
212 * CMU-CH control register bit definitions:
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
221 * CMU-CH ECC UE AFSR bit definitions:
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
232 * CMU-CH pci control register bits:
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
240 * CMU-CH PCI asynchronous fault status register bit definitions:
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
256 * CMU-CH PCI diagnostic register bit definitions:
258 #define PCMU_PCI_DIAG_DIS_DWSYNC 0x0000000000000010ull
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)
265 #define PCMU_ID_TO_IGN(pcmu_id) ((pcmu_ign_t)UPAID_TO_IGN(pcmu_id))
269 * Number of dispatch target entries.
271 #define U2U_DATA_NUM 16
274 * Offsets of registers in the Interrupt Dispatch Table:
276 #define U2U_MODE_STATUS_REGISTER_OFFSET 0x00000000
277 #define U2U_PID_REGISTER_OFFSET 0x00000008
278 #define U2U_DATA_REGISTER_OFFSET 0x00000010
281 * Mode Status register bit definitions:
283 #define U2U_MS_IEV 0x00000040 /* bit-6: Interrupt Extension enable */
286 * Index number of U2U registers in OBP's "regs-property" of CMU-CH
288 #define REGS_INDEX_OF_U2U 3
291 * The following two difinitions are used to control target id
292 * for Interrupt dispatch data by software.
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 */
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
;
310 * Driver binding name for OPL DC system
312 #define PCICMU_OPL_DC_BINDING_NAME "pci10cf,1390"
315 * Offsets of registers in the interrupt block:
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
325 * Offsets of registers in the ECC block:
327 #define PCMU_ECC_CSR_OFFSET 0x20
328 #define PCMU_UE_AFSR_OFFSET 0x30
329 #define PCMU_UE_AFAR_OFFSET 0x38
332 * CMU-CH control register bit definitions:
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
341 * CMU-CH interrupt mapping register bit definitions:
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
351 * CMU-CH clear interrupt register bit definitions:
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
360 * CMU-CH ECC control register bit definitions:
362 #define PCMU_ECC_CTRL_ECC_EN 0x8000000000000000ull
363 #define PCMU_ECC_CTRL_UE_INTEN 0x4000000000000000ull
366 * CMU-CH ECC UE AFSR bit definitions:
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
374 * CMU-CH PCI diagnostic register bit definitions:
376 #define PCMU_PCI_DIAG_DIS_RETRY 0x0000000000000040ull
377 #define PCMU_PCI_DIAG_DIS_INTSYNC 0x0000000000000020ull
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)
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 */
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
;
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
*,
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
);
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
);
454 #endif /* _SYS_PCICMU_H */