kernel: remove unused utsname_set_machine()
[unleashed.git] / usr / src / uts / sun4u / opl / io / pcicmu / pcicmu.c
blobfe42ecf6c25f01f338b09f71e9ceee84e3d55451
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
28 * OPL CMU-CH PCI nexus driver.
32 #include <sys/types.h>
33 #include <sys/sysmacros.h>
34 #include <sys/systm.h>
35 #include <sys/intreg.h>
36 #include <sys/intr.h>
37 #include <sys/machsystm.h>
38 #include <sys/conf.h>
39 #include <sys/stat.h>
40 #include <sys/kmem.h>
41 #include <sys/async.h>
42 #include <sys/ivintr.h>
43 #include <sys/sunddi.h>
44 #include <sys/sunndi.h>
45 #include <sys/ndifm.h>
46 #include <sys/ontrap.h>
47 #include <sys/ddi_impldefs.h>
48 #include <sys/ddi_subrdefs.h>
49 #include <sys/epm.h>
50 #include <sys/spl.h>
51 #include <sys/fm/util.h>
52 #include <sys/fm/util.h>
53 #include <sys/fm/protocol.h>
54 #include <sys/fm/io/pci.h>
55 #include <sys/fm/io/sun4upci.h>
56 #include <sys/pcicmu/pcicmu.h>
58 #include <sys/cmn_err.h>
59 #include <sys/time.h>
60 #include <sys/pci.h>
61 #include <sys/modctl.h>
62 #include <sys/open.h>
63 #include <sys/errno.h>
64 #include <sys/file.h>
67 uint32_t pcmu_spurintr_duration = 60000000; /* One minute */
70 * The variable controls the default setting of the command register
71 * for pci devices. See pcmu_init_child() for details.
73 * This flags also controls the setting of bits in the bridge control
74 * register pci to pci bridges. See pcmu_init_child() for details.
76 ushort_t pcmu_command_default = PCI_COMM_SERR_ENABLE |
77 PCI_COMM_WAIT_CYC_ENAB |
78 PCI_COMM_PARITY_DETECT |
79 PCI_COMM_ME |
80 PCI_COMM_MAE |
81 PCI_COMM_IO;
83 * The following driver parameters are defined as variables to allow
84 * patching for debugging and tuning. Flags that can be set on a per
85 * PBM basis are bit fields where the PBM device instance number maps
86 * to the bit position.
88 #ifdef DEBUG
89 uint64_t pcmu_debug_flags = 0;
90 #endif
91 uint_t ecc_error_intr_enable = 1;
93 uint_t pcmu_ecc_afsr_retries = 100; /* XXX - what's a good value? */
95 uint_t pcmu_intr_retry_intv = 5; /* for interrupt retry reg */
96 uint_t pcmu_panic_on_fatal_errors = 1; /* should be 1 at beta */
98 hrtime_t pcmu_intrpend_timeout = 5ll * NANOSEC; /* 5 seconds in nanoseconds */
100 uint64_t pcmu_errtrig_pa = 0x0;
104 * The following value is the number of consecutive unclaimed interrupts that
105 * will be tolerated for a particular ino_p before the interrupt is deemed to
106 * be jabbering and is blocked.
108 uint_t pcmu_unclaimed_intr_max = 20;
111 * function prototypes for dev ops routines:
113 static int pcmu_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
114 static int pcmu_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
115 static int pcmu_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
116 void *arg, void **result);
117 static int pcmu_open(dev_t *devp, int flags, int otyp, cred_t *credp);
118 static int pcmu_close(dev_t dev, int flags, int otyp, cred_t *credp);
119 static int pcmu_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
120 cred_t *credp, int *rvalp);
121 static int pcmu_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
122 int flags, char *name, caddr_t valuep, int *lengthp);
123 static int pcmu_ctlops_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args);
124 static int pcmu_ctlops_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args,
125 void *result);
127 static int map_pcmu_registers(pcmu_t *, dev_info_t *);
128 static void unmap_pcmu_registers(pcmu_t *);
129 static void pcmu_pbm_clear_error(pcmu_pbm_t *);
131 static int pcmu_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
132 void *, void *);
133 static int pcmu_map(dev_info_t *, dev_info_t *, ddi_map_req_t *,
134 off_t, off_t, caddr_t *);
135 static int pcmu_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t,
136 ddi_intr_handle_impl_t *, void *);
138 static uint32_t pcmu_identity_init(pcmu_t *pcmu_p);
139 static int pcmu_intr_setup(pcmu_t *pcmu_p);
140 static void pcmu_pbm_errstate_get(pcmu_t *pcmu_p,
141 pcmu_pbm_errstate_t *pbm_err_p);
142 static int pcmu_obj_setup(pcmu_t *pcmu_p);
143 static void pcmu_obj_destroy(pcmu_t *pcmu_p);
144 static void pcmu_obj_resume(pcmu_t *pcmu_p);
145 static void pcmu_obj_suspend(pcmu_t *pcmu_p);
147 static void u2u_ittrans_init(pcmu_t *, u2u_ittrans_data_t **);
148 static void u2u_ittrans_resume(u2u_ittrans_data_t **);
149 static void u2u_ittrans_uninit(u2u_ittrans_data_t *);
151 static pcmu_ksinfo_t *pcmu_name_kstat;
154 * bus ops and dev ops structures:
156 static struct bus_ops pcmu_bus_ops = {
157 BUSO_REV,
158 pcmu_map,
162 i_ddi_map_fault,
171 pcmu_ctlops,
172 ddi_bus_prop_op,
173 ndi_busop_get_eventcookie, /* (*bus_get_eventcookie)(); */
174 ndi_busop_add_eventcall, /* (*bus_add_eventcall)(); */
175 ndi_busop_remove_eventcall, /* (*bus_remove_eventcall)(); */
176 ndi_post_event, /* (*bus_post_event)(); */
177 NULL, /* (*bus_intr_ctl)(); */
178 NULL, /* (*bus_config)(); */
179 NULL, /* (*bus_unconfig)(); */
180 NULL, /* (*bus_fm_init)(); */
181 NULL, /* (*bus_fm_fini)(); */
182 NULL, /* (*bus_fm_access_enter)(); */
183 NULL, /* (*bus_fm_access_fini)(); */
184 NULL, /* (*bus_power)(); */
185 pcmu_intr_ops /* (*bus_intr_op)(); */
188 struct cb_ops pcmu_cb_ops = {
189 pcmu_open, /* open */
190 pcmu_close, /* close */
191 nodev, /* strategy */
192 nodev, /* print */
193 nodev, /* dump */
194 nodev, /* read */
195 nodev, /* write */
196 pcmu_ioctl, /* ioctl */
197 nodev, /* devmap */
198 nodev, /* mmap */
199 nodev, /* segmap */
200 nochpoll, /* poll */
201 pcmu_prop_op, /* cb_prop_op */
202 NULL, /* streamtab */
203 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */
204 CB_REV, /* rev */
205 nodev, /* int (*cb_aread)() */
206 nodev /* int (*cb_awrite)() */
209 static struct dev_ops pcmu_ops = {
210 DEVO_REV,
212 pcmu_info,
213 nulldev,
215 pcmu_attach,
216 pcmu_detach,
217 nodev,
218 &pcmu_cb_ops,
219 &pcmu_bus_ops,
221 ddi_quiesce_not_needed, /* quiesce */
226 * module definitions:
228 extern struct mod_ops mod_driverops;
230 static struct modldrv modldrv = {
231 &mod_driverops, /* Type of module - driver */
232 "OPL CMU-CH PCI Nexus driver", /* Name of module. */
233 &pcmu_ops, /* driver ops */
236 static struct modlinkage modlinkage = {
237 MODREV_1, (void *)&modldrv, NULL
241 * driver global data:
243 void *per_pcmu_state; /* per-pbm soft state pointer */
244 kmutex_t pcmu_global_mutex; /* attach/detach common struct lock */
245 errorq_t *pcmu_ecc_queue = NULL; /* per-system ecc handling queue */
247 extern void pcmu_child_cfg_save(dev_info_t *dip);
248 extern void pcmu_child_cfg_restore(dev_info_t *dip);
251 _init(void)
253 int e;
256 * Initialize per-pci bus soft state pointer.
258 e = ddi_soft_state_init(&per_pcmu_state, sizeof (pcmu_t), 1);
259 if (e != 0)
260 return (e);
263 * Initialize global mutexes.
265 mutex_init(&pcmu_global_mutex, NULL, MUTEX_DRIVER, NULL);
268 * Create the performance kstats.
270 pcmu_kstat_init();
273 * Install the module.
275 e = mod_install(&modlinkage);
276 if (e != 0) {
277 ddi_soft_state_fini(&per_pcmu_state);
278 mutex_destroy(&pcmu_global_mutex);
280 return (e);
284 _fini(void)
286 int e;
289 * Remove the module.
291 e = mod_remove(&modlinkage);
292 if (e != 0) {
293 return (e);
297 * Destroy pcmu_ecc_queue, and set it to NULL.
299 if (pcmu_ecc_queue) {
300 errorq_destroy(pcmu_ecc_queue);
301 pcmu_ecc_queue = NULL;
305 * Destroy the performance kstats.
307 pcmu_kstat_fini();
310 * Free the per-pci and per-CMU-CH soft state info and destroy
311 * mutex for per-CMU-CH soft state.
313 ddi_soft_state_fini(&per_pcmu_state);
314 mutex_destroy(&pcmu_global_mutex);
315 return (e);
319 _info(struct modinfo *modinfop)
321 return (mod_info(&modlinkage, modinfop));
324 /*ARGSUSED*/
325 static int
326 pcmu_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
328 int instance = getminor((dev_t)arg) >> 8;
329 pcmu_t *pcmu_p = get_pcmu_soft_state(instance);
331 switch (infocmd) {
332 case DDI_INFO_DEVT2INSTANCE:
333 *result = (void *)(uintptr_t)instance;
334 return (DDI_SUCCESS);
336 case DDI_INFO_DEVT2DEVINFO:
337 if (pcmu_p == NULL)
338 return (DDI_FAILURE);
339 *result = (void *)pcmu_p->pcmu_dip;
340 return (DDI_SUCCESS);
342 default:
343 return (DDI_FAILURE);
348 /* device driver entry points */
350 * attach entry point:
352 static int
353 pcmu_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
355 pcmu_t *pcmu_p;
356 int instance = ddi_get_instance(dip);
358 switch (cmd) {
359 case DDI_ATTACH:
360 PCMU_DBG0(PCMU_DBG_ATTACH, dip, "DDI_ATTACH\n");
363 * Allocate and get the per-pci soft state structure.
365 if (alloc_pcmu_soft_state(instance) != DDI_SUCCESS) {
366 cmn_err(CE_WARN, "%s%d: can't allocate pci state",
367 ddi_driver_name(dip), instance);
368 goto err_bad_pcmu_softstate;
370 pcmu_p = get_pcmu_soft_state(instance);
371 pcmu_p->pcmu_dip = dip;
372 mutex_init(&pcmu_p->pcmu_mutex, NULL, MUTEX_DRIVER, NULL);
373 pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_CLOSED;
374 pcmu_p->pcmu_open_count = 0;
377 * Get key properties of the pci bridge node.
379 if (get_pcmu_properties(pcmu_p, dip) == DDI_FAILURE) {
380 goto err_bad_pcmu_prop;
384 * Map in the registers.
386 if (map_pcmu_registers(pcmu_p, dip) == DDI_FAILURE) {
387 goto err_bad_reg_prop;
389 if (pcmu_obj_setup(pcmu_p) != DDI_SUCCESS) {
390 goto err_bad_objs;
393 if (ddi_create_minor_node(dip, "devctl", S_IFCHR,
394 (uint_t)instance<<8 | 0xff,
395 DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
396 goto err_bad_devctl_node;
400 * Due to unresolved hardware issues, disable PCIPM until
401 * the problem is fully understood.
403 * pcmu_pwr_setup(pcmu_p, dip);
406 ddi_report_dev(dip);
408 pcmu_p->pcmu_state = PCMU_ATTACHED;
409 PCMU_DBG0(PCMU_DBG_ATTACH, dip, "attach success\n");
410 break;
412 err_bad_objs:
413 ddi_remove_minor_node(dip, "devctl");
414 err_bad_devctl_node:
415 unmap_pcmu_registers(pcmu_p);
416 err_bad_reg_prop:
417 free_pcmu_properties(pcmu_p);
418 err_bad_pcmu_prop:
419 mutex_destroy(&pcmu_p->pcmu_mutex);
420 free_pcmu_soft_state(instance);
421 err_bad_pcmu_softstate:
422 return (DDI_FAILURE);
424 case DDI_RESUME:
425 PCMU_DBG0(PCMU_DBG_ATTACH, dip, "DDI_RESUME\n");
428 * Make sure the CMU-CH control registers
429 * are configured properly.
431 pcmu_p = get_pcmu_soft_state(instance);
432 mutex_enter(&pcmu_p->pcmu_mutex);
435 * Make sure this instance has been suspended.
437 if (pcmu_p->pcmu_state != PCMU_SUSPENDED) {
438 PCMU_DBG0(PCMU_DBG_ATTACH, dip,
439 "instance NOT suspended\n");
440 mutex_exit(&pcmu_p->pcmu_mutex);
441 return (DDI_FAILURE);
443 pcmu_obj_resume(pcmu_p);
444 pcmu_p->pcmu_state = PCMU_ATTACHED;
446 pcmu_child_cfg_restore(dip);
448 mutex_exit(&pcmu_p->pcmu_mutex);
449 break;
451 default:
452 PCMU_DBG0(PCMU_DBG_ATTACH, dip, "unsupported attach op\n");
453 return (DDI_FAILURE);
456 return (DDI_SUCCESS);
460 * detach entry point:
462 static int
463 pcmu_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
465 int instance = ddi_get_instance(dip);
466 pcmu_t *pcmu_p = get_pcmu_soft_state(instance);
467 int len;
470 * Make sure we are currently attached
472 if (pcmu_p->pcmu_state != PCMU_ATTACHED) {
473 PCMU_DBG0(PCMU_DBG_ATTACH, dip,
474 "failed - instance not attached\n");
475 return (DDI_FAILURE);
478 mutex_enter(&pcmu_p->pcmu_mutex);
480 switch (cmd) {
481 case DDI_DETACH:
482 PCMU_DBG0(PCMU_DBG_DETACH, dip, "DDI_DETACH\n");
483 pcmu_obj_destroy(pcmu_p);
486 * Free the pci soft state structure and the rest of the
487 * resources it's using.
489 free_pcmu_properties(pcmu_p);
490 unmap_pcmu_registers(pcmu_p);
491 mutex_exit(&pcmu_p->pcmu_mutex);
492 mutex_destroy(&pcmu_p->pcmu_mutex);
493 free_pcmu_soft_state(instance);
495 /* Free the interrupt-priorities prop if we created it. */
496 if (ddi_getproplen(DDI_DEV_T_ANY, dip,
497 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
498 "interrupt-priorities", &len) == DDI_PROP_SUCCESS) {
499 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip,
500 "interrupt-priorities");
502 return (DDI_SUCCESS);
504 case DDI_SUSPEND:
505 pcmu_child_cfg_save(dip);
506 pcmu_obj_suspend(pcmu_p);
507 pcmu_p->pcmu_state = PCMU_SUSPENDED;
509 mutex_exit(&pcmu_p->pcmu_mutex);
510 return (DDI_SUCCESS);
512 default:
513 PCMU_DBG0(PCMU_DBG_DETACH, dip, "unsupported detach op\n");
514 mutex_exit(&pcmu_p->pcmu_mutex);
515 return (DDI_FAILURE);
519 /* ARGSUSED3 */
520 static int
521 pcmu_open(dev_t *devp, int flags, int otyp, cred_t *credp)
523 pcmu_t *pcmu_p;
525 if (otyp != OTYP_CHR) {
526 return (EINVAL);
530 * Get the soft state structure for the device.
532 pcmu_p = DEV_TO_SOFTSTATE(*devp);
533 if (pcmu_p == NULL) {
534 return (ENXIO);
538 * Handle the open by tracking the device state.
540 PCMU_DBG2(PCMU_DBG_OPEN, pcmu_p->pcmu_dip,
541 "devp=%x: flags=%x\n", devp, flags);
542 mutex_enter(&pcmu_p->pcmu_mutex);
543 if (flags & FEXCL) {
544 if (pcmu_p->pcmu_soft_state != PCMU_SOFT_STATE_CLOSED) {
545 mutex_exit(&pcmu_p->pcmu_mutex);
546 PCMU_DBG0(PCMU_DBG_OPEN, pcmu_p->pcmu_dip, "busy\n");
547 return (EBUSY);
549 pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_OPEN_EXCL;
550 } else {
551 if (pcmu_p->pcmu_soft_state == PCMU_SOFT_STATE_OPEN_EXCL) {
552 mutex_exit(&pcmu_p->pcmu_mutex);
553 PCMU_DBG0(PCMU_DBG_OPEN, pcmu_p->pcmu_dip, "busy\n");
554 return (EBUSY);
556 pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_OPEN;
558 pcmu_p->pcmu_open_count++;
559 mutex_exit(&pcmu_p->pcmu_mutex);
560 return (0);
564 /* ARGSUSED */
565 static int
566 pcmu_close(dev_t dev, int flags, int otyp, cred_t *credp)
568 pcmu_t *pcmu_p;
570 if (otyp != OTYP_CHR) {
571 return (EINVAL);
574 pcmu_p = DEV_TO_SOFTSTATE(dev);
575 if (pcmu_p == NULL) {
576 return (ENXIO);
579 PCMU_DBG2(PCMU_DBG_CLOSE, pcmu_p->pcmu_dip,
580 "dev=%x: flags=%x\n", dev, flags);
581 mutex_enter(&pcmu_p->pcmu_mutex);
582 pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_CLOSED;
583 pcmu_p->pcmu_open_count = 0;
584 mutex_exit(&pcmu_p->pcmu_mutex);
585 return (0);
588 /* ARGSUSED */
589 static int
590 pcmu_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
591 cred_t *credp, int *rvalp)
593 pcmu_t *pcmu_p;
594 dev_info_t *dip;
595 struct devctl_iocdata *dcp;
596 uint_t bus_state;
597 int rv = 0;
599 pcmu_p = DEV_TO_SOFTSTATE(dev);
600 if (pcmu_p == NULL) {
601 return (ENXIO);
604 dip = pcmu_p->pcmu_dip;
605 PCMU_DBG2(PCMU_DBG_IOCTL, dip, "dev=%x: cmd=%x\n", dev, cmd);
608 * We can use the generic implementation for these ioctls
610 switch (cmd) {
611 case DEVCTL_DEVICE_GETSTATE:
612 case DEVCTL_DEVICE_ONLINE:
613 case DEVCTL_DEVICE_OFFLINE:
614 case DEVCTL_BUS_GETSTATE:
615 return (ndi_devctl_ioctl(dip, cmd, arg, mode, 0));
619 * read devctl ioctl data
621 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
622 return (EFAULT);
624 switch (cmd) {
626 case DEVCTL_DEVICE_RESET:
627 PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_DEVICE_RESET\n");
628 rv = ENOTSUP;
629 break;
632 case DEVCTL_BUS_QUIESCE:
633 PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_QUIESCE\n");
634 if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS) {
635 if (bus_state == BUS_QUIESCED) {
636 break;
639 (void) ndi_set_bus_state(dip, BUS_QUIESCED);
640 break;
642 case DEVCTL_BUS_UNQUIESCE:
643 PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_UNQUIESCE\n");
644 if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS) {
645 if (bus_state == BUS_ACTIVE) {
646 break;
649 (void) ndi_set_bus_state(dip, BUS_ACTIVE);
650 break;
652 case DEVCTL_BUS_RESET:
653 PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_RESET\n");
654 rv = ENOTSUP;
655 break;
657 case DEVCTL_BUS_RESETALL:
658 PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_RESETALL\n");
659 rv = ENOTSUP;
660 break;
662 default:
663 rv = ENOTTY;
666 ndi_dc_freehdl(dcp);
667 return (rv);
670 static int pcmu_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
671 int flags, char *name, caddr_t valuep, int *lengthp)
673 return (ddi_prop_op(dev, dip, prop_op, flags, name, valuep, lengthp));
675 /* bus driver entry points */
678 * bus map entry point:
680 * if map request is for an rnumber
681 * get the corresponding regspec from device node
682 * build a new regspec in our parent's format
683 * build a new map_req with the new regspec
684 * call up the tree to complete the mapping
686 static int
687 pcmu_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
688 off_t off, off_t len, caddr_t *addrp)
690 pcmu_t *pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip));
691 struct regspec p_regspec;
692 ddi_map_req_t p_mapreq;
693 int reglen, rval, r_no;
694 pci_regspec_t reloc_reg, *rp = &reloc_reg;
696 PCMU_DBG2(PCMU_DBG_MAP, dip, "rdip=%s%d:",
697 ddi_driver_name(rdip), ddi_get_instance(rdip));
699 if (mp->map_flags & DDI_MF_USER_MAPPING) {
700 return (DDI_ME_UNIMPLEMENTED);
703 switch (mp->map_type) {
704 case DDI_MT_REGSPEC:
705 reloc_reg = *(pci_regspec_t *)mp->map_obj.rp; /* dup whole */
706 break;
708 case DDI_MT_RNUMBER:
709 r_no = mp->map_obj.rnumber;
710 PCMU_DBG1(PCMU_DBG_MAP | PCMU_DBG_CONT, dip, " r#=%x", r_no);
712 if (ddi_getlongprop(DDI_DEV_T_NONE, rdip, DDI_PROP_DONTPASS,
713 "reg", (caddr_t)&rp, &reglen) != DDI_SUCCESS) {
714 return (DDI_ME_RNUMBER_RANGE);
717 if (r_no < 0 || r_no >= reglen / sizeof (pci_regspec_t)) {
718 kmem_free(rp, reglen);
719 return (DDI_ME_RNUMBER_RANGE);
721 rp += r_no;
722 break;
724 default:
725 return (DDI_ME_INVAL);
727 PCMU_DBG0(PCMU_DBG_MAP | PCMU_DBG_CONT, dip, "\n");
729 /* use "assigned-addresses" to relocate regspec within pci space */
730 if (rval = pcmu_reloc_reg(dip, rdip, pcmu_p, rp)) {
731 goto done;
734 /* adjust regspec according to mapping request */
735 if (len) {
736 rp->pci_size_low = (uint_t)len;
738 rp->pci_phys_low += off;
740 /* use "ranges" to translate relocated pci regspec into parent space */
741 if (rval = pcmu_xlate_reg(pcmu_p, rp, &p_regspec)) {
742 goto done;
745 p_mapreq = *mp; /* dup the whole structure */
746 p_mapreq.map_type = DDI_MT_REGSPEC;
747 p_mapreq.map_obj.rp = &p_regspec;
748 rval = ddi_map(dip, &p_mapreq, 0, 0, addrp);
750 done:
751 if (mp->map_type == DDI_MT_RNUMBER) {
752 kmem_free(rp - r_no, reglen);
754 return (rval);
757 #ifdef DEBUG
758 int pcmu_peekfault_cnt = 0;
759 int pcmu_pokefault_cnt = 0;
760 #endif /* DEBUG */
762 static int
763 pcmu_do_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args)
765 pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p;
766 int err = DDI_SUCCESS;
767 on_trap_data_t otd;
769 mutex_enter(&pcbm_p->pcbm_pokeflt_mutex);
770 pcbm_p->pcbm_ontrap_data = &otd;
772 /* Set up protected environment. */
773 if (!on_trap(&otd, OT_DATA_ACCESS)) {
774 uintptr_t tramp = otd.ot_trampoline;
776 otd.ot_trampoline = (uintptr_t)&poke_fault;
777 err = do_poke(in_args->size, (void *)in_args->dev_addr,
778 (void *)in_args->host_addr);
779 otd.ot_trampoline = tramp;
780 } else {
781 err = DDI_FAILURE;
785 * Read the async fault register for the PBM to see it sees
786 * a master-abort.
788 pcmu_pbm_clear_error(pcbm_p);
790 if (otd.ot_trap & OT_DATA_ACCESS) {
791 err = DDI_FAILURE;
794 /* Take down protected environment. */
795 no_trap();
797 pcbm_p->pcbm_ontrap_data = NULL;
798 mutex_exit(&pcbm_p->pcbm_pokeflt_mutex);
800 #ifdef DEBUG
801 if (err == DDI_FAILURE)
802 pcmu_pokefault_cnt++;
803 #endif
804 return (err);
808 static int
809 pcmu_ctlops_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args)
811 return (pcmu_do_poke(pcmu_p, in_args));
814 /* ARGSUSED */
815 static int
816 pcmu_do_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args)
818 int err = DDI_SUCCESS;
819 on_trap_data_t otd;
821 if (!on_trap(&otd, OT_DATA_ACCESS)) {
822 uintptr_t tramp = otd.ot_trampoline;
824 otd.ot_trampoline = (uintptr_t)&peek_fault;
825 err = do_peek(in_args->size, (void *)in_args->dev_addr,
826 (void *)in_args->host_addr);
827 otd.ot_trampoline = tramp;
828 } else
829 err = DDI_FAILURE;
831 no_trap();
833 #ifdef DEBUG
834 if (err == DDI_FAILURE)
835 pcmu_peekfault_cnt++;
836 #endif
837 return (err);
841 static int
842 pcmu_ctlops_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args, void *result)
844 result = (void *)in_args->host_addr;
845 return (pcmu_do_peek(pcmu_p, in_args));
849 * control ops entry point:
851 * Requests handled completely:
852 * DDI_CTLOPS_INITCHILD see pcmu_init_child() for details
853 * DDI_CTLOPS_UNINITCHILD
854 * DDI_CTLOPS_REPORTDEV see report_dev() for details
855 * DDI_CTLOPS_XLATE_INTRS nothing to do
856 * DDI_CTLOPS_IOMIN cache line size if streaming otherwise 1
857 * DDI_CTLOPS_REGSIZE
858 * DDI_CTLOPS_NREGS
859 * DDI_CTLOPS_NINTRS
860 * DDI_CTLOPS_DVMAPAGESIZE
861 * DDI_CTLOPS_POKE
862 * DDI_CTLOPS_PEEK
863 * DDI_CTLOPS_QUIESCE
864 * DDI_CTLOPS_UNQUIESCE
866 * All others passed to parent.
868 static int
869 pcmu_ctlops(dev_info_t *dip, dev_info_t *rdip,
870 ddi_ctl_enum_t op, void *arg, void *result)
872 pcmu_t *pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip));
874 switch (op) {
875 case DDI_CTLOPS_INITCHILD:
876 return (pcmu_init_child(pcmu_p, (dev_info_t *)arg));
878 case DDI_CTLOPS_UNINITCHILD:
879 return (pcmu_uninit_child(pcmu_p, (dev_info_t *)arg));
881 case DDI_CTLOPS_REPORTDEV:
882 return (pcmu_report_dev(rdip));
884 case DDI_CTLOPS_IOMIN:
886 * If we are using the streaming cache, align at
887 * least on a cache line boundary. Otherwise use
888 * whatever alignment is passed in.
890 return (DDI_SUCCESS);
892 case DDI_CTLOPS_REGSIZE:
893 *((off_t *)result) = pcmu_get_reg_set_size(rdip, *((int *)arg));
894 return (DDI_SUCCESS);
896 case DDI_CTLOPS_NREGS:
897 *((uint_t *)result) = pcmu_get_nreg_set(rdip);
898 return (DDI_SUCCESS);
900 case DDI_CTLOPS_DVMAPAGESIZE:
901 *((ulong_t *)result) = 0;
902 return (DDI_SUCCESS);
904 case DDI_CTLOPS_POKE:
905 return (pcmu_ctlops_poke(pcmu_p, (peekpoke_ctlops_t *)arg));
907 case DDI_CTLOPS_PEEK:
908 return (pcmu_ctlops_peek(pcmu_p, (peekpoke_ctlops_t *)arg,
909 result));
911 case DDI_CTLOPS_AFFINITY:
912 break;
914 case DDI_CTLOPS_QUIESCE:
915 return (DDI_FAILURE);
917 case DDI_CTLOPS_UNQUIESCE:
918 return (DDI_FAILURE);
920 default:
921 break;
925 * Now pass the request up to our parent.
927 PCMU_DBG2(PCMU_DBG_CTLOPS, dip,
928 "passing request to parent: rdip=%s%d\n",
929 ddi_driver_name(rdip), ddi_get_instance(rdip));
930 return (ddi_ctlops(dip, rdip, op, arg, result));
934 /* ARGSUSED */
935 static int
936 pcmu_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
937 ddi_intr_handle_impl_t *hdlp, void *result)
939 pcmu_t *pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip));
940 int ret = DDI_SUCCESS;
942 switch (intr_op) {
943 case DDI_INTROP_GETCAP:
944 /* GetCap will always fail for all non PCI devices */
945 (void) pci_intx_get_cap(rdip, (int *)result);
946 break;
947 case DDI_INTROP_SETCAP:
948 ret = DDI_ENOTSUP;
949 break;
950 case DDI_INTROP_ALLOC:
951 *(int *)result = hdlp->ih_scratch1;
952 break;
953 case DDI_INTROP_FREE:
954 break;
955 case DDI_INTROP_GETPRI:
956 *(int *)result = hdlp->ih_pri ? hdlp->ih_pri : 0;
957 break;
958 case DDI_INTROP_SETPRI:
959 break;
960 case DDI_INTROP_ADDISR:
961 ret = pcmu_add_intr(dip, rdip, hdlp);
962 break;
963 case DDI_INTROP_REMISR:
964 ret = pcmu_remove_intr(dip, rdip, hdlp);
965 break;
966 case DDI_INTROP_ENABLE:
967 ret = pcmu_ib_update_intr_state(pcmu_p, rdip, hdlp,
968 PCMU_INTR_STATE_ENABLE);
969 break;
970 case DDI_INTROP_DISABLE:
971 ret = pcmu_ib_update_intr_state(pcmu_p, rdip, hdlp,
972 PCMU_INTR_STATE_DISABLE);
973 break;
974 case DDI_INTROP_SETMASK:
975 ret = pci_intx_set_mask(rdip);
976 break;
977 case DDI_INTROP_CLRMASK:
978 ret = pci_intx_clr_mask(rdip);
979 break;
980 case DDI_INTROP_GETPENDING:
981 ret = pci_intx_get_pending(rdip, (int *)result);
982 break;
983 case DDI_INTROP_NINTRS:
984 case DDI_INTROP_NAVAIL:
985 *(int *)result = i_ddi_get_intx_nintrs(rdip);
986 break;
987 case DDI_INTROP_SUPPORTED_TYPES:
988 /* PCI nexus driver supports only fixed interrupts */
989 *(int *)result = i_ddi_get_intx_nintrs(rdip) ?
990 DDI_INTR_TYPE_FIXED : 0;
991 break;
992 default:
993 ret = DDI_ENOTSUP;
994 break;
997 return (ret);
1001 * CMU-CH specifics implementation:
1002 * interrupt mapping register
1003 * PBM configuration
1004 * ECC and PBM error handling
1007 /* called by pcmu_attach() DDI_ATTACH to initialize pci objects */
1008 static int
1009 pcmu_obj_setup(pcmu_t *pcmu_p)
1011 int ret;
1013 mutex_enter(&pcmu_global_mutex);
1014 pcmu_p->pcmu_rev = ddi_prop_get_int(DDI_DEV_T_ANY, pcmu_p->pcmu_dip,
1015 DDI_PROP_DONTPASS, "module-revision#", 0);
1017 pcmu_ib_create(pcmu_p);
1018 pcmu_cb_create(pcmu_p);
1019 pcmu_ecc_create(pcmu_p);
1020 pcmu_pbm_create(pcmu_p);
1021 pcmu_err_create(pcmu_p);
1022 if ((ret = pcmu_intr_setup(pcmu_p)) != DDI_SUCCESS)
1023 goto done;
1026 * Due to a hardware bug, do not create kstat for DC systems
1027 * with PCI hw revision less than 5.
1029 if ((strncmp(ddi_binding_name(pcmu_p->pcmu_dip),
1030 PCICMU_OPL_DC_BINDING_NAME, strlen(PCICMU_OPL_DC_BINDING_NAME))
1031 != 0) || (pcmu_p->pcmu_rev > 4)) {
1032 pcmu_kstat_create(pcmu_p);
1034 done:
1035 mutex_exit(&pcmu_global_mutex);
1036 if (ret != DDI_SUCCESS) {
1037 cmn_err(CE_NOTE, "Interrupt register failure, returning 0x%x\n",
1038 ret);
1040 return (ret);
1043 /* called by pcmu_detach() DDI_DETACH to destroy pci objects */
1044 static void
1045 pcmu_obj_destroy(pcmu_t *pcmu_p)
1047 mutex_enter(&pcmu_global_mutex);
1049 pcmu_kstat_destroy(pcmu_p);
1050 pcmu_pbm_destroy(pcmu_p);
1051 pcmu_err_destroy(pcmu_p);
1052 pcmu_ecc_destroy(pcmu_p);
1053 pcmu_cb_destroy(pcmu_p);
1054 pcmu_ib_destroy(pcmu_p);
1055 pcmu_intr_teardown(pcmu_p);
1057 mutex_exit(&pcmu_global_mutex);
1060 /* called by pcmu_attach() DDI_RESUME to (re)initialize pci objects */
1061 static void
1062 pcmu_obj_resume(pcmu_t *pcmu_p)
1064 mutex_enter(&pcmu_global_mutex);
1066 pcmu_ib_configure(pcmu_p->pcmu_ib_p);
1067 pcmu_ecc_configure(pcmu_p);
1068 pcmu_ib_resume(pcmu_p->pcmu_ib_p);
1069 u2u_ittrans_resume((u2u_ittrans_data_t **)
1070 &(pcmu_p->pcmu_cb_p->pcb_ittrans_cookie));
1072 pcmu_pbm_configure(pcmu_p->pcmu_pcbm_p);
1074 pcmu_cb_resume(pcmu_p->pcmu_cb_p);
1076 pcmu_pbm_resume(pcmu_p->pcmu_pcbm_p);
1078 mutex_exit(&pcmu_global_mutex);
1081 /* called by pcmu_detach() DDI_SUSPEND to suspend pci objects */
1082 static void
1083 pcmu_obj_suspend(pcmu_t *pcmu_p)
1085 mutex_enter(&pcmu_global_mutex);
1087 pcmu_pbm_suspend(pcmu_p->pcmu_pcbm_p);
1088 pcmu_ib_suspend(pcmu_p->pcmu_ib_p);
1089 pcmu_cb_suspend(pcmu_p->pcmu_cb_p);
1091 mutex_exit(&pcmu_global_mutex);
1094 static int
1095 pcmu_intr_setup(pcmu_t *pcmu_p)
1097 dev_info_t *dip = pcmu_p->pcmu_dip;
1098 pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p;
1099 pcmu_cb_t *pcb_p = pcmu_p->pcmu_cb_p;
1100 int i, no_of_intrs;
1103 * Get the interrupts property.
1105 if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
1106 "interrupts", (caddr_t)&pcmu_p->pcmu_inos,
1107 &pcmu_p->pcmu_inos_len) != DDI_SUCCESS) {
1108 cmn_err(CE_PANIC, "%s%d: no interrupts property\n",
1109 ddi_driver_name(dip), ddi_get_instance(dip));
1113 * figure out number of interrupts in the "interrupts" property
1114 * and convert them all into ino.
1116 i = ddi_getprop(DDI_DEV_T_ANY, dip, 0, "#interrupt-cells", 1);
1117 i = CELLS_1275_TO_BYTES(i);
1118 no_of_intrs = pcmu_p->pcmu_inos_len / i;
1119 for (i = 0; i < no_of_intrs; i++) {
1120 pcmu_p->pcmu_inos[i] =
1121 PCMU_IB_MONDO_TO_INO(pcmu_p->pcmu_inos[i]);
1124 pcb_p->pcb_no_of_inos = no_of_intrs;
1125 if (i = pcmu_ecc_register_intr(pcmu_p)) {
1126 goto teardown;
1129 intr_dist_add(pcmu_cb_intr_dist, pcb_p);
1130 pcmu_ecc_enable_intr(pcmu_p);
1132 if (i = pcmu_pbm_register_intr(pcbm_p)) {
1133 intr_dist_rem(pcmu_cb_intr_dist, pcb_p);
1134 goto teardown;
1136 intr_dist_add(pcmu_pbm_intr_dist, pcbm_p);
1137 pcmu_ib_intr_enable(pcmu_p, pcmu_p->pcmu_inos[CBNINTR_PBM]);
1139 intr_dist_add_weighted(pcmu_ib_intr_dist_all, pcmu_p->pcmu_ib_p);
1140 return (DDI_SUCCESS);
1141 teardown:
1142 pcmu_intr_teardown(pcmu_p);
1143 return (i);
1147 * pcmu_fix_ranges - fixes the config space entry of the "ranges"
1148 * property on CMU-CH platforms
1150 void
1151 pcmu_fix_ranges(pcmu_ranges_t *rng_p, int rng_entries)
1153 int i;
1154 for (i = 0; i < rng_entries; i++, rng_p++) {
1155 if ((rng_p->child_high & PCI_REG_ADDR_M) == PCI_ADDR_CONFIG)
1156 rng_p->parent_low |= rng_p->child_high;
1161 * map_pcmu_registers
1163 * This function is called from the attach routine to map the registers
1164 * accessed by this driver.
1166 * used by: pcmu_attach()
1168 * return value: DDI_FAILURE on failure
1170 static int
1171 map_pcmu_registers(pcmu_t *pcmu_p, dev_info_t *dip)
1173 ddi_device_acc_attr_t attr;
1175 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1176 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1178 attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
1179 if (ddi_regs_map_setup(dip, 0, &pcmu_p->pcmu_address[0], 0, 0,
1180 &attr, &pcmu_p->pcmu_ac[0]) != DDI_SUCCESS) {
1181 cmn_err(CE_WARN, "%s%d: unable to map reg entry 0\n",
1182 ddi_driver_name(dip), ddi_get_instance(dip));
1183 return (DDI_FAILURE);
1187 * We still use pcmu_address[2]
1189 if (ddi_regs_map_setup(dip, 2, &pcmu_p->pcmu_address[2], 0, 0,
1190 &attr, &pcmu_p->pcmu_ac[2]) != DDI_SUCCESS) {
1191 cmn_err(CE_WARN, "%s%d: unable to map reg entry 2\n",
1192 ddi_driver_name(dip), ddi_get_instance(dip));
1193 ddi_regs_map_free(&pcmu_p->pcmu_ac[0]);
1194 return (DDI_FAILURE);
1198 * The second register set contains the bridge's configuration
1199 * header. This header is at the very beginning of the bridge's
1200 * configuration space. This space has litte-endian byte order.
1202 attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
1203 if (ddi_regs_map_setup(dip, 1, &pcmu_p->pcmu_address[1], 0,
1204 PCI_CONF_HDR_SIZE, &attr, &pcmu_p->pcmu_ac[1]) != DDI_SUCCESS) {
1206 cmn_err(CE_WARN, "%s%d: unable to map reg entry 1\n",
1207 ddi_driver_name(dip), ddi_get_instance(dip));
1208 ddi_regs_map_free(&pcmu_p->pcmu_ac[0]);
1209 return (DDI_FAILURE);
1211 PCMU_DBG2(PCMU_DBG_ATTACH, dip, "address (%p,%p)\n",
1212 pcmu_p->pcmu_address[0], pcmu_p->pcmu_address[1]);
1213 return (DDI_SUCCESS);
1217 * unmap_pcmu_registers:
1219 * This routine unmap the registers mapped by map_pcmu_registers.
1221 * used by: pcmu_detach()
1223 * return value: none
1225 static void
1226 unmap_pcmu_registers(pcmu_t *pcmu_p)
1228 ddi_regs_map_free(&pcmu_p->pcmu_ac[0]);
1229 ddi_regs_map_free(&pcmu_p->pcmu_ac[1]);
1230 ddi_regs_map_free(&pcmu_p->pcmu_ac[2]);
1234 * These convenience wrappers relies on map_pcmu_registers() to setup
1235 * pcmu_address[0-2] correctly at first.
1237 static uintptr_t
1238 get_reg_base(pcmu_t *pcmu_p)
1240 return ((uintptr_t)pcmu_p->pcmu_address[2]);
1243 /* The CMU-CH config reg base is always the 2nd reg entry */
1244 static uintptr_t
1245 get_config_reg_base(pcmu_t *pcmu_p)
1247 return ((uintptr_t)(pcmu_p->pcmu_address[1]));
1250 uint64_t
1251 ib_get_map_reg(pcmu_ib_mondo_t mondo, uint32_t cpu_id)
1253 return ((mondo) | (cpu_id << PCMU_INTR_MAP_REG_TID_SHIFT) |
1254 PCMU_INTR_MAP_REG_VALID);
1258 uint32_t
1259 ib_map_reg_get_cpu(volatile uint64_t reg)
1261 return ((reg & PCMU_INTR_MAP_REG_TID) >>
1262 PCMU_INTR_MAP_REG_TID_SHIFT);
1265 uint64_t *
1266 ib_intr_map_reg_addr(pcmu_ib_t *pib_p, pcmu_ib_ino_t ino)
1268 uint64_t *addr;
1270 ASSERT(ino & 0x20);
1271 addr = (uint64_t *)(pib_p->pib_obio_intr_map_regs +
1272 (((uint_t)ino & 0x1f) << 3));
1273 return (addr);
1276 uint64_t *
1277 ib_clear_intr_reg_addr(pcmu_ib_t *pib_p, pcmu_ib_ino_t ino)
1279 uint64_t *addr;
1281 ASSERT(ino & 0x20);
1282 addr = (uint64_t *)(pib_p->pib_obio_clear_intr_regs +
1283 (((uint_t)ino & 0x1f) << 3));
1284 return (addr);
1287 uintptr_t
1288 pcmu_ib_setup(pcmu_ib_t *pib_p)
1290 pcmu_t *pcmu_p = pib_p->pib_pcmu_p;
1291 uintptr_t a = get_reg_base(pcmu_p);
1293 pib_p->pib_ign = PCMU_ID_TO_IGN(pcmu_p->pcmu_id);
1294 pib_p->pib_max_ino = PCMU_MAX_INO;
1295 pib_p->pib_obio_intr_map_regs = a + PCMU_IB_OBIO_INTR_MAP_REG_OFFSET;
1296 pib_p->pib_obio_clear_intr_regs =
1297 a + PCMU_IB_OBIO_CLEAR_INTR_REG_OFFSET;
1298 return (a);
1302 * Return the cpuid to to be used for an ino.
1304 * On multi-function pci devices, functions have separate devinfo nodes and
1305 * interrupts.
1307 * This function determines if there is already an established slot-oriented
1308 * interrupt-to-cpu binding established, if there is then it returns that
1309 * cpu. Otherwise a new cpu is selected by intr_dist_cpuid().
1311 * The devinfo node we are trying to associate a cpu with is
1312 * ino_p->pino_ih_head->ih_dip.
1314 uint32_t
1315 pcmu_intr_dist_cpuid(pcmu_ib_t *pib_p, pcmu_ib_ino_info_t *ino_p)
1317 dev_info_t *rdip = ino_p->pino_ih_head->ih_dip;
1318 dev_info_t *prdip = ddi_get_parent(rdip);
1319 pcmu_ib_ino_info_t *sino_p;
1320 dev_info_t *sdip;
1321 dev_info_t *psdip;
1322 char *buf1 = NULL, *buf2 = NULL;
1323 char *s1, *s2, *s3;
1324 int l2;
1325 int cpu_id;
1327 /* must be CMU-CH driver parent (not ebus) */
1328 if (strcmp(ddi_driver_name(prdip), "pcicmu") != 0)
1329 goto newcpu;
1332 * From PCI 1275 binding: 2.2.1.3 Unit Address representation:
1333 * Since the "unit-number" is the address that appears in on Open
1334 * Firmware 'device path', it follows that only the DD and DD,FF
1335 * forms of the text representation can appear in a 'device path'.
1337 * The rdip unit address is of the form "DD[,FF]". Define two
1338 * unit address strings that represent same-slot use: "DD" and "DD,".
1339 * The first compare uses strcmp, the second uses strncmp.
1341 s1 = ddi_get_name_addr(rdip);
1342 if (s1 == NULL) {
1343 goto newcpu;
1346 buf1 = kmem_alloc(MAXNAMELEN, KM_SLEEP); /* strcmp */
1347 buf2 = kmem_alloc(MAXNAMELEN, KM_SLEEP); /* strncmp */
1348 s1 = strcpy(buf1, s1);
1349 s2 = strcpy(buf2, s1);
1351 s1 = strrchr(s1, ',');
1352 if (s1) {
1353 *s1 = '\0'; /* have "DD,FF" */
1354 s1 = buf1; /* search via strcmp "DD" */
1356 s2 = strrchr(s2, ',');
1357 *(s2 + 1) = '\0';
1358 s2 = buf2;
1359 l2 = strlen(s2); /* search via strncmp "DD," */
1360 } else {
1361 (void) strcat(s2, ","); /* have "DD" */
1362 l2 = strlen(s2); /* search via strncmp "DD," */
1366 * Search the established ino list for devinfo nodes bound
1367 * to an ino that matches one of the slot use strings.
1369 ASSERT(MUTEX_HELD(&pib_p->pib_ino_lst_mutex));
1370 for (sino_p = pib_p->pib_ino_lst; sino_p; sino_p = sino_p->pino_next) {
1371 /* skip self and non-established */
1372 if ((sino_p == ino_p) || (sino_p->pino_established == 0))
1373 continue;
1375 /* skip non-siblings */
1376 sdip = sino_p->pino_ih_head->ih_dip;
1377 psdip = ddi_get_parent(sdip);
1378 if (psdip != prdip)
1379 continue;
1381 /* must be CMU-CH driver parent (not ebus) */
1382 if (strcmp(ddi_driver_name(psdip), "pcicmu") != 0)
1383 continue;
1385 s3 = ddi_get_name_addr(sdip);
1386 if ((s1 && (strcmp(s1, s3) == 0)) ||
1387 (strncmp(s2, s3, l2) == 0)) {
1388 extern int intr_dist_debug;
1390 if (intr_dist_debug) {
1391 cmn_err(CE_CONT, "intr_dist: "
1392 "pcicmu`pcmu_intr_dist_cpuid "
1393 "%s#%d %s: cpu %d established "
1394 "by %s#%d %s\n", ddi_driver_name(rdip),
1395 ddi_get_instance(rdip),
1396 ddi_deviname(rdip, buf1),
1397 sino_p->pino_cpuid,
1398 ddi_driver_name(sdip),
1399 ddi_get_instance(sdip),
1400 ddi_deviname(sdip, buf2));
1402 break;
1406 /* If a slot use match is found then use established cpu */
1407 if (sino_p) {
1408 cpu_id = sino_p->pino_cpuid; /* target established cpu */
1409 goto out;
1412 newcpu: cpu_id = intr_dist_cpuid(); /* target new cpu */
1414 out: if (buf1)
1415 kmem_free(buf1, MAXNAMELEN);
1416 if (buf2)
1417 kmem_free(buf2, MAXNAMELEN);
1418 return (cpu_id);
1421 void
1422 pcmu_cb_teardown(pcmu_t *pcmu_p)
1424 pcmu_cb_t *pcb_p = pcmu_p->pcmu_cb_p;
1426 u2u_ittrans_uninit((u2u_ittrans_data_t *)pcb_p->pcb_ittrans_cookie);
1430 pcmu_ecc_add_intr(pcmu_t *pcmu_p, int inum, pcmu_ecc_intr_info_t *eii_p)
1432 uint32_t mondo;
1434 mondo = ((pcmu_p->pcmu_cb_p->pcb_ign << PCMU_INO_BITS) |
1435 pcmu_p->pcmu_inos[inum]);
1437 VERIFY(add_ivintr(mondo, pcmu_pil[inum], (intrfunc)pcmu_ecc_intr,
1438 (caddr_t)eii_p, NULL, NULL) == 0);
1440 return (PCMU_ATTACH_RETCODE(PCMU_ECC_OBJ,
1441 PCMU_OBJ_INTR_ADD, DDI_SUCCESS));
1444 /* ARGSUSED */
1445 void
1446 pcmu_ecc_rem_intr(pcmu_t *pcmu_p, int inum, pcmu_ecc_intr_info_t *eii_p)
1448 uint32_t mondo;
1450 mondo = ((pcmu_p->pcmu_cb_p->pcb_ign << PCMU_INO_BITS) |
1451 pcmu_p->pcmu_inos[inum]);
1453 VERIFY(rem_ivintr(mondo, pcmu_pil[inum]) == 0);
1456 void
1457 pcmu_pbm_configure(pcmu_pbm_t *pcbm_p)
1459 pcmu_t *pcmu_p = pcbm_p->pcbm_pcmu_p;
1460 dev_info_t *dip = pcmu_p->pcmu_dip;
1462 #define pbm_err ((PCMU_PCI_AFSR_E_MASK << PCMU_PCI_AFSR_PE_SHIFT) | \
1463 (PCMU_PCI_AFSR_E_MASK << PCMU_PCI_AFSR_SE_SHIFT))
1464 #define csr_err (PCI_STAT_PERROR | PCI_STAT_S_PERROR | \
1465 PCI_STAT_R_MAST_AB | PCI_STAT_R_TARG_AB | \
1466 PCI_STAT_S_TARG_AB | PCI_STAT_S_PERROR)
1469 * Clear any PBM errors.
1471 *pcbm_p->pcbm_async_flt_status_reg = pbm_err;
1474 * Clear error bits in configuration status register.
1476 PCMU_DBG1(PCMU_DBG_ATTACH, dip,
1477 "pcmu_pbm_configure: conf status reg=%x\n", csr_err);
1479 pcbm_p->pcbm_config_header->ch_status_reg = csr_err;
1481 PCMU_DBG1(PCMU_DBG_ATTACH, dip,
1482 "pcmu_pbm_configure: conf status reg==%x\n",
1483 pcbm_p->pcbm_config_header->ch_status_reg);
1485 (void) ndi_prop_update_int(DDI_DEV_T_ANY, dip, "latency-timer",
1486 (int)pcbm_p->pcbm_config_header->ch_latency_timer_reg);
1487 #undef pbm_err
1488 #undef csr_err
1491 uint_t
1492 pcmu_pbm_disable_errors(pcmu_pbm_t *pcbm_p)
1494 pcmu_t *pcmu_p = pcbm_p->pcbm_pcmu_p;
1495 pcmu_ib_t *pib_p = pcmu_p->pcmu_ib_p;
1498 * Disable error and streaming byte hole interrupts via the
1499 * PBM control register.
1501 *pcbm_p->pcbm_ctrl_reg &= ~PCMU_PCI_CTRL_ERR_INT_EN;
1504 * Disable error interrupts via the interrupt mapping register.
1506 pcmu_ib_intr_disable(pib_p,
1507 pcmu_p->pcmu_inos[CBNINTR_PBM], PCMU_IB_INTR_NOWAIT);
1508 return (BF_NONE);
1511 void
1512 pcmu_cb_setup(pcmu_t *pcmu_p)
1514 uint64_t csr, csr_pa, pa;
1515 pcmu_cb_t *pcb_p = pcmu_p->pcmu_cb_p;
1517 pcb_p->pcb_ign = PCMU_ID_TO_IGN(pcmu_p->pcmu_id);
1518 pa = (uint64_t)hat_getpfnum(kas.a_hat, pcmu_p->pcmu_address[0]);
1519 pcb_p->pcb_base_pa = pa = pa >> (32 - MMU_PAGESHIFT) << 32;
1520 pcb_p->pcb_map_pa = pa + PCMU_IB_OBIO_INTR_MAP_REG_OFFSET;
1521 pcb_p->pcb_clr_pa = pa + PCMU_IB_OBIO_CLEAR_INTR_REG_OFFSET;
1522 pcb_p->pcb_obsta_pa = pa + PCMU_IB_OBIO_INTR_STATE_DIAG_REG;
1524 csr_pa = pa + PCMU_CB_CONTROL_STATUS_REG_OFFSET;
1525 csr = lddphysio(csr_pa);
1528 * Clear any pending address parity errors.
1530 if (csr & PCMU_CB_CONTROL_STATUS_APERR) {
1531 csr |= PCMU_CB_CONTROL_STATUS_APERR;
1532 cmn_err(CE_WARN, "clearing UPA address parity error\n");
1534 csr |= PCMU_CB_CONTROL_STATUS_APCKEN;
1535 csr &= ~PCMU_CB_CONTROL_STATUS_IAP;
1536 stdphysio(csr_pa, csr);
1538 u2u_ittrans_init(pcmu_p,
1539 (u2u_ittrans_data_t **)&pcb_p->pcb_ittrans_cookie);
1542 void
1543 pcmu_ecc_setup(pcmu_ecc_t *pecc_p)
1545 pecc_p->pecc_ue.pecc_errpndg_mask = 0;
1546 pecc_p->pecc_ue.pecc_offset_mask = PCMU_ECC_UE_AFSR_DW_OFFSET;
1547 pecc_p->pecc_ue.pecc_offset_shift = PCMU_ECC_UE_AFSR_DW_OFFSET_SHIFT;
1548 pecc_p->pecc_ue.pecc_size_log2 = 3;
1551 static uintptr_t
1552 get_pbm_reg_base(pcmu_t *pcmu_p)
1554 return ((uintptr_t)(pcmu_p->pcmu_address[0]));
1557 void
1558 pcmu_pbm_setup(pcmu_pbm_t *pcbm_p)
1560 pcmu_t *pcmu_p = pcbm_p->pcbm_pcmu_p;
1563 * Get the base virtual address for the PBM control block.
1565 uintptr_t a = get_pbm_reg_base(pcmu_p);
1568 * Get the virtual address of the PCI configuration header.
1569 * This should be mapped little-endian.
1571 pcbm_p->pcbm_config_header =
1572 (config_header_t *)get_config_reg_base(pcmu_p);
1575 * Get the virtual addresses for control, error and diag
1576 * registers.
1578 pcbm_p->pcbm_ctrl_reg = (uint64_t *)(a + PCMU_PCI_CTRL_REG_OFFSET);
1579 pcbm_p->pcbm_diag_reg = (uint64_t *)(a + PCMU_PCI_DIAG_REG_OFFSET);
1580 pcbm_p->pcbm_async_flt_status_reg =
1581 (uint64_t *)(a + PCMU_PCI_ASYNC_FLT_STATUS_REG_OFFSET);
1582 pcbm_p->pcbm_async_flt_addr_reg =
1583 (uint64_t *)(a + PCMU_PCI_ASYNC_FLT_ADDR_REG_OFFSET);
1586 /*ARGSUSED*/
1587 void
1588 pcmu_pbm_teardown(pcmu_pbm_t *pcbm_p)
1593 pcmu_get_numproxy(dev_info_t *dip)
1595 return (ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1596 "#upa-interrupt-proxies", 1));
1600 pcmu_get_portid(dev_info_t *dip)
1602 return (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1603 "portid", -1));
1607 * CMU-CH Performance Events.
1609 static pcmu_kev_mask_t
1610 pcicmu_pcmu_events[] = {
1611 {"pio_cycles_b", 0xf}, {"interrupts", 0x11},
1612 {"upa_inter_nack", 0x12}, {"pio_reads", 0x13},
1613 {"pio_writes", 0x14},
1614 {"clear_pic", 0x1f}
1618 * Create the picN kstat's.
1620 void
1621 pcmu_kstat_init()
1623 pcmu_name_kstat = (pcmu_ksinfo_t *)kmem_alloc(sizeof (pcmu_ksinfo_t),
1624 KM_NOSLEEP);
1626 if (pcmu_name_kstat == NULL) {
1627 cmn_err(CE_WARN, "pcicmu : no space for kstat\n");
1628 } else {
1629 pcmu_name_kstat->pic_no_evs =
1630 sizeof (pcicmu_pcmu_events) / sizeof (pcmu_kev_mask_t);
1631 pcmu_name_kstat->pic_shift[0] = PCMU_SHIFT_PIC0;
1632 pcmu_name_kstat->pic_shift[1] = PCMU_SHIFT_PIC1;
1633 pcmu_create_name_kstat("pcmup",
1634 pcmu_name_kstat, pcicmu_pcmu_events);
1639 * Called from _fini()
1641 void
1642 pcmu_kstat_fini()
1644 if (pcmu_name_kstat != NULL) {
1645 pcmu_delete_name_kstat(pcmu_name_kstat);
1646 kmem_free(pcmu_name_kstat, sizeof (pcmu_ksinfo_t));
1647 pcmu_name_kstat = NULL;
1652 * Create the performance 'counters' kstat.
1654 void
1655 pcmu_add_upstream_kstat(pcmu_t *pcmu_p)
1657 pcmu_cntr_pa_t *cntr_pa_p = &pcmu_p->pcmu_uks_pa;
1658 uint64_t regbase = va_to_pa((void *)get_reg_base(pcmu_p));
1660 cntr_pa_p->pcr_pa = regbase + PCMU_PERF_PCR_OFFSET;
1661 cntr_pa_p->pic_pa = regbase + PCMU_PERF_PIC_OFFSET;
1662 pcmu_p->pcmu_uksp = pcmu_create_cntr_kstat(pcmu_p, "pcmup",
1663 NUM_OF_PICS, pcmu_cntr_kstat_pa_update, cntr_pa_p);
1667 * u2u_ittrans_init() is caled from in pci.c's pcmu_cb_setup() per CMU.
1668 * Second argument "ittrans_cookie" is address of pcb_ittrans_cookie in
1669 * pcb_p member. allocated interrupt block is returned in it.
1671 static void
1672 u2u_ittrans_init(pcmu_t *pcmu_p, u2u_ittrans_data_t **ittrans_cookie)
1675 u2u_ittrans_data_t *u2u_trans_p;
1676 ddi_device_acc_attr_t attr;
1677 int ret;
1678 int board;
1681 * Allocate the data structure to support U2U's
1682 * interrupt target translations.
1684 u2u_trans_p = (u2u_ittrans_data_t *)
1685 kmem_zalloc(sizeof (u2u_ittrans_data_t), KM_SLEEP);
1688 * Get other properties, "board#"
1690 board = ddi_getprop(DDI_DEV_T_ANY, pcmu_p->pcmu_dip,
1691 DDI_PROP_DONTPASS, "board#", -1);
1693 u2u_trans_p->u2u_board = board;
1695 if (board == -1) {
1696 /* this cannot happen on production systems */
1697 cmn_err(CE_PANIC, "u2u:Invalid property;board = %d", board);
1701 * Initialize interrupt target translations mutex.
1703 mutex_init(&(u2u_trans_p->u2u_ittrans_lock), "u2u_ittrans_lock",
1704 MUTEX_DEFAULT, NULL);
1707 * Get U2U's registers space by ddi_regs_map_setup(9F)
1709 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1710 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1711 attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
1713 ret = ddi_regs_map_setup(pcmu_p->pcmu_dip,
1714 REGS_INDEX_OF_U2U, (caddr_t *)(&(u2u_trans_p->u2u_regs_base)),
1715 0, 0, &attr, &(u2u_trans_p->u2u_acc));
1718 * check result of ddi_regs_map_setup().
1720 if (ret != DDI_SUCCESS) {
1721 cmn_err(CE_PANIC, "u2u%d: registers map setup failed", board);
1725 * Read Port-id(1 byte) in u2u
1727 u2u_trans_p->u2u_port_id = *(volatile int32_t *)
1728 (u2u_trans_p->u2u_regs_base + U2U_PID_REGISTER_OFFSET);
1730 if (pcmu_p->pcmu_id != u2u_trans_p->u2u_port_id) {
1731 cmn_err(CE_PANIC, "u2u%d: Invalid Port-ID", board);
1734 *ittrans_cookie = u2u_trans_p;
1738 * u2u_ittras_resume() is called from pcmu_obj_resume() at DDI_RESUME entry.
1740 static void
1741 u2u_ittrans_resume(u2u_ittrans_data_t **ittrans_cookie)
1744 u2u_ittrans_data_t *u2u_trans_p;
1745 u2u_ittrans_id_t *ittrans_id_p;
1746 uintptr_t data_reg_addr;
1747 int ix;
1749 u2u_trans_p = *ittrans_cookie;
1752 * Set U2U Data Register
1754 for (ix = 0; ix < U2U_DATA_NUM; ix++) {
1755 ittrans_id_p = &(u2u_trans_p->u2u_ittrans_id[ix]);
1756 data_reg_addr = u2u_trans_p->u2u_regs_base +
1757 U2U_DATA_REGISTER_OFFSET + (ix * sizeof (uint64_t));
1758 if (ittrans_id_p->u2u_ino_map_reg == NULL) {
1759 /* This index was not set */
1760 continue;
1762 *(volatile uint32_t *) (data_reg_addr) =
1763 (uint32_t)ittrans_id_p->u2u_tgt_cpu_id;
1769 * u2u_ittras_uninit() is called from ib_destroy() at detach,
1770 * or occuring error in attach.
1772 static void
1773 u2u_ittrans_uninit(u2u_ittrans_data_t *ittrans_cookie)
1776 if (ittrans_cookie == NULL) {
1777 return; /* not support */
1780 if (ittrans_cookie == (u2u_ittrans_data_t *)(-1)) {
1781 return; /* illeagal case */
1784 ddi_regs_map_free(&(ittrans_cookie->u2u_acc));
1785 mutex_destroy(&(ittrans_cookie->u2u_ittrans_lock));
1786 kmem_free((void *)ittrans_cookie, sizeof (u2u_ittrans_data_t));
1790 * This routine,u2u_translate_tgtid(, , cpu_id, pino_map_reg),
1791 * searches index having same value of pino_map_reg, or empty.
1792 * Then, stores cpu_id in a U2U Data Register as this index,
1793 * and return this index.
1796 u2u_translate_tgtid(pcmu_t *pcmu_p, uint_t cpu_id,
1797 volatile uint64_t *pino_map_reg)
1800 int index = -1;
1801 int ix;
1802 int err_level; /* severity level for cmn_err */
1803 u2u_ittrans_id_t *ittrans_id_p;
1804 uintptr_t data_reg_addr;
1805 u2u_ittrans_data_t *ittrans_cookie;
1807 ittrans_cookie =
1808 (u2u_ittrans_data_t *)(pcmu_p->pcmu_cb_p->pcb_ittrans_cookie);
1810 if (ittrans_cookie == NULL) {
1811 return (cpu_id);
1814 if (ittrans_cookie == (u2u_ittrans_data_t *)(-1)) {
1815 return (-1); /* illeagal case */
1818 mutex_enter(&(ittrans_cookie->u2u_ittrans_lock));
1821 * Decide index No. of U2U Data registers in either
1822 * already used by same pino_map_reg, or empty.
1824 for (ix = 0; ix < U2U_DATA_NUM; ix++) {
1825 ittrans_id_p = &(ittrans_cookie->u2u_ittrans_id[ix]);
1826 if (ittrans_id_p->u2u_ino_map_reg == pino_map_reg) {
1827 /* already used this pino_map_reg */
1828 index = ix;
1829 break;
1831 if (index == -1 &&
1832 ittrans_id_p->u2u_ino_map_reg == NULL) {
1833 index = ix;
1837 if (index == -1) {
1838 if (panicstr) {
1839 err_level = CE_WARN;
1840 } else {
1841 err_level = CE_PANIC;
1843 cmn_err(err_level, "u2u%d:No more U2U-Data regs!!",
1844 ittrans_cookie->u2u_board);
1845 return (cpu_id);
1849 * For U2U
1850 * set cpu_id into u2u_data_reg by index.
1851 * ((uint64_t)(u2u_regs_base
1852 * + U2U_DATA_REGISTER_OFFSET))[index] = cpu_id;
1855 data_reg_addr = ittrans_cookie->u2u_regs_base
1856 + U2U_DATA_REGISTER_OFFSET
1857 + (index * sizeof (uint64_t));
1860 * Set cpu_id into U2U Data register[index]
1862 *(volatile uint32_t *) (data_reg_addr) = (uint32_t)cpu_id;
1865 * Setup for software, excepting at panicing.
1866 * and rebooting, etc...?
1868 if (!panicstr) {
1869 ittrans_id_p = &(ittrans_cookie->u2u_ittrans_id[index]);
1870 ittrans_id_p->u2u_tgt_cpu_id = cpu_id;
1871 ittrans_id_p->u2u_ino_map_reg = pino_map_reg;
1874 mutex_exit(&(ittrans_cookie->u2u_ittrans_lock));
1876 return (index);
1880 * u2u_ittrans_cleanup() is called from common_pcmu_ib_intr_disable()
1881 * after called intr_rem_cpu(mondo).
1883 void
1884 u2u_ittrans_cleanup(u2u_ittrans_data_t *ittrans_cookie,
1885 volatile uint64_t *pino_map_reg)
1888 int ix;
1889 u2u_ittrans_id_t *ittrans_id_p;
1891 if (ittrans_cookie == NULL) {
1892 return;
1895 if (ittrans_cookie == (u2u_ittrans_data_t *)(-1)) {
1896 return; /* illeagal case */
1899 mutex_enter(&(ittrans_cookie->u2u_ittrans_lock));
1901 for (ix = 0; ix < U2U_DATA_NUM; ix++) {
1902 ittrans_id_p = &(ittrans_cookie->u2u_ittrans_id[ix]);
1903 if (ittrans_id_p->u2u_ino_map_reg == pino_map_reg) {
1904 ittrans_id_p->u2u_ino_map_reg = NULL;
1905 break;
1909 mutex_exit(&(ittrans_cookie->u2u_ittrans_lock));
1913 * pcmu_ecc_classify, called by ecc_handler to classify ecc errors
1914 * and determine if we should panic or not.
1916 void
1917 pcmu_ecc_classify(uint64_t err, pcmu_ecc_errstate_t *ecc_err_p)
1919 struct async_flt *ecc = &ecc_err_p->ecc_aflt;
1920 /* LINTED */
1921 pcmu_t *pcmu_p = ecc_err_p->ecc_ii_p.pecc_p->pecc_pcmu_p;
1923 ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex));
1925 ecc_err_p->ecc_bridge_type = PCI_OPLCMU; /* RAGS */
1927 * Get the parent bus id that caused the error.
1929 ecc_err_p->ecc_dev_id = (ecc_err_p->ecc_afsr & PCMU_ECC_UE_AFSR_ID)
1930 >> PCMU_ECC_UE_AFSR_ID_SHIFT;
1932 * Determine the doubleword offset of the error.
1934 ecc_err_p->ecc_dw_offset = (ecc_err_p->ecc_afsr &
1935 PCMU_ECC_UE_AFSR_DW_OFFSET) >> PCMU_ECC_UE_AFSR_DW_OFFSET_SHIFT;
1937 * Determine the primary error type.
1939 switch (err) {
1940 case PCMU_ECC_UE_AFSR_E_PIO:
1941 if (ecc_err_p->pecc_pri) {
1942 ecc->flt_erpt_class = PCI_ECC_PIO_UE;
1943 } else {
1944 ecc->flt_erpt_class = PCI_ECC_SEC_PIO_UE;
1946 /* For CMU-CH, a UE is always fatal. */
1947 ecc->flt_panic = 1;
1948 break;
1950 default:
1951 return;
1956 * pcmu_pbm_classify, called by pcmu_pbm_afsr_report to classify piow afsr.
1959 pcmu_pbm_classify(pcmu_pbm_errstate_t *pbm_err_p)
1961 uint32_t e;
1962 int nerr = 0;
1963 char **tmp_class;
1965 if (pbm_err_p->pcbm_pri) {
1966 tmp_class = &pbm_err_p->pcbm_pci.pcmu_err_class;
1967 e = PBM_AFSR_TO_PRIERR(pbm_err_p->pbm_afsr);
1968 pbm_err_p->pbm_log = FM_LOG_PCI;
1969 } else {
1970 tmp_class = &pbm_err_p->pbm_err_class;
1971 e = PBM_AFSR_TO_SECERR(pbm_err_p->pbm_afsr);
1972 pbm_err_p->pbm_log = FM_LOG_PBM;
1975 if (e & PCMU_PCI_AFSR_E_MA) {
1976 *tmp_class = pbm_err_p->pcbm_pri ? PCI_MA : PCI_SEC_MA;
1977 nerr++;
1979 return (nerr);
1983 * Function used to clear PBM/PCI/IOMMU error state after error handling
1984 * is complete. Only clearing error bits which have been logged. Called by
1985 * pcmu_pbm_err_handler and pcmu_bus_exit.
1987 static void
1988 pcmu_clear_error(pcmu_t *pcmu_p, pcmu_pbm_errstate_t *pbm_err_p)
1990 pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p;
1992 ASSERT(MUTEX_HELD(&pcbm_p->pcbm_pcmu_p->pcmu_err_mutex));
1994 *pcbm_p->pcbm_ctrl_reg = pbm_err_p->pbm_ctl_stat;
1995 *pcbm_p->pcbm_async_flt_status_reg = pbm_err_p->pbm_afsr;
1996 pcbm_p->pcbm_config_header->ch_status_reg =
1997 pbm_err_p->pcbm_pci.pcmu_cfg_stat;
2000 /*ARGSUSED*/
2002 pcmu_pbm_err_handler(dev_info_t *dip, ddi_fm_error_t *derr,
2003 const void *impl_data, int caller)
2005 int fatal = 0;
2006 int nonfatal = 0;
2007 int unknown = 0;
2008 uint32_t prierr, secerr;
2009 pcmu_pbm_errstate_t pbm_err;
2010 pcmu_t *pcmu_p = (pcmu_t *)impl_data;
2011 int ret = 0;
2013 ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex));
2014 pcmu_pbm_errstate_get(pcmu_p, &pbm_err);
2016 derr->fme_ena = derr->fme_ena ? derr->fme_ena :
2017 fm_ena_generate(0, FM_ENA_FMT1);
2019 prierr = PBM_AFSR_TO_PRIERR(pbm_err.pbm_afsr);
2020 secerr = PBM_AFSR_TO_SECERR(pbm_err.pbm_afsr);
2022 if (derr->fme_flag == DDI_FM_ERR_PEEK) {
2024 * For ddi_peek treat all events as nonfatal. We only
2025 * really call this function so that pcmu_clear_error()
2026 * and ndi_fm_handler_dispatch() will get called.
2028 nonfatal++;
2029 goto done;
2030 } else if (derr->fme_flag == DDI_FM_ERR_POKE) {
2032 * For ddi_poke we can treat as nonfatal if the
2033 * following conditions are met :
2034 * 1. Make sure only primary error is MA/TA
2035 * 2. Make sure no secondary error
2036 * 3. check pci config header stat reg to see MA/TA is
2037 * logged. We cannot verify only MA/TA is recorded
2038 * since it gets much more complicated when a
2039 * PCI-to-PCI bridge is present.
2041 if ((prierr == PCMU_PCI_AFSR_E_MA) && !secerr &&
2042 (pbm_err.pcbm_pci.pcmu_cfg_stat & PCI_STAT_R_MAST_AB)) {
2043 nonfatal++;
2044 goto done;
2048 if (prierr || secerr) {
2049 ret = pcmu_pbm_afsr_report(dip, derr->fme_ena, &pbm_err);
2050 if (ret == DDI_FM_FATAL) {
2051 fatal++;
2052 } else {
2053 nonfatal++;
2057 ret = pcmu_cfg_report(dip, derr, &pbm_err.pcbm_pci, caller, prierr);
2058 if (ret == DDI_FM_FATAL) {
2059 fatal++;
2060 } else if (ret == DDI_FM_NONFATAL) {
2061 nonfatal++;
2064 done:
2065 if (ret == DDI_FM_FATAL) {
2066 fatal++;
2067 } else if (ret == DDI_FM_NONFATAL) {
2068 nonfatal++;
2069 } else if (ret == DDI_FM_UNKNOWN) {
2070 unknown++;
2073 /* Cleanup and reset error bits */
2074 pcmu_clear_error(pcmu_p, &pbm_err);
2076 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
2077 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
2081 pcmu_check_error(pcmu_t *pcmu_p)
2083 pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p;
2084 uint16_t pcmu_cfg_stat;
2085 uint64_t pbm_afsr;
2087 ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex));
2089 pcmu_cfg_stat = pcbm_p->pcbm_config_header->ch_status_reg;
2090 pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg;
2092 if ((pcmu_cfg_stat & (PCI_STAT_S_PERROR | PCI_STAT_S_TARG_AB |
2093 PCI_STAT_R_TARG_AB | PCI_STAT_R_MAST_AB |
2094 PCI_STAT_S_SYSERR | PCI_STAT_PERROR)) ||
2095 (PBM_AFSR_TO_PRIERR(pbm_afsr))) {
2096 return (1);
2098 return (0);
2103 * Function used to gather PBM/PCI error state for the
2104 * pcmu_pbm_err_handler. This function must be called while pcmu_err_mutex
2105 * is held.
2107 static void
2108 pcmu_pbm_errstate_get(pcmu_t *pcmu_p, pcmu_pbm_errstate_t *pbm_err_p)
2110 pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p;
2112 ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex));
2113 bzero(pbm_err_p, sizeof (pcmu_pbm_errstate_t));
2116 * Capture all pbm error state for later logging
2118 pbm_err_p->pbm_bridge_type = PCI_OPLCMU; /* RAGS */
2119 pbm_err_p->pcbm_pci.pcmu_cfg_stat =
2120 pcbm_p->pcbm_config_header->ch_status_reg;
2121 pbm_err_p->pbm_ctl_stat = *pcbm_p->pcbm_ctrl_reg;
2122 pbm_err_p->pcbm_pci.pcmu_cfg_comm =
2123 pcbm_p->pcbm_config_header->ch_command_reg;
2124 pbm_err_p->pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg;
2125 pbm_err_p->pbm_afar = *pcbm_p->pcbm_async_flt_addr_reg;
2126 pbm_err_p->pcbm_pci.pcmu_pa = *pcbm_p->pcbm_async_flt_addr_reg;
2129 static void
2130 pcmu_pbm_clear_error(pcmu_pbm_t *pcbm_p)
2132 uint64_t pbm_afsr;
2135 * for poke() support - called from POKE_FLUSH. Spin waiting
2136 * for MA, TA or SERR to be cleared by a pcmu_pbm_error_intr().
2137 * We have to wait for SERR too in case the device is beyond
2138 * a pci-pci bridge.
2140 pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg;
2141 while (((pbm_afsr >> PCMU_PCI_AFSR_PE_SHIFT) &
2142 (PCMU_PCI_AFSR_E_MA | PCMU_PCI_AFSR_E_TA))) {
2143 pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg;
2147 void
2148 pcmu_err_create(pcmu_t *pcmu_p)
2151 * PCI detected ECC errorq, to schedule async handling
2152 * of ECC errors and logging.
2153 * The errorq is created here but destroyed when _fini is called
2154 * for the pci module.
2156 if (pcmu_ecc_queue == NULL) {
2157 pcmu_ecc_queue = errorq_create("pcmu_ecc_queue",
2158 (errorq_func_t)pcmu_ecc_err_drain,
2159 NULL,
2160 ECC_MAX_ERRS, sizeof (pcmu_ecc_errstate_t),
2161 PIL_2, ERRORQ_VITAL);
2162 if (pcmu_ecc_queue == NULL)
2163 panic("failed to create required system error queue");
2167 * Initialize error handling mutex.
2169 mutex_init(&pcmu_p->pcmu_err_mutex, NULL, MUTEX_DRIVER,
2170 (void *)pcmu_p->pcmu_fm_ibc);
2173 void
2174 pcmu_err_destroy(pcmu_t *pcmu_p)
2176 mutex_destroy(&pcmu_p->pcmu_err_mutex);
2180 * Function used to post PCI block module specific ereports.
2182 void
2183 pcmu_pbm_ereport_post(dev_info_t *dip, uint64_t ena,
2184 pcmu_pbm_errstate_t *pbm_err)
2186 char *aux_msg;
2187 uint32_t prierr, secerr;
2188 pcmu_t *pcmu_p;
2189 int instance = ddi_get_instance(dip);
2191 ena = ena ? ena : fm_ena_generate(0, FM_ENA_FMT1);
2193 pcmu_p = get_pcmu_soft_state(instance);
2194 prierr = PBM_AFSR_TO_PRIERR(pbm_err->pbm_afsr);
2195 secerr = PBM_AFSR_TO_SECERR(pbm_err->pbm_afsr);
2196 if (prierr)
2197 aux_msg = "PCI primary error: Master Abort";
2198 else if (secerr)
2199 aux_msg = "PCI secondary error: Master Abort";
2200 else
2201 aux_msg = "";
2202 cmn_err(CE_WARN, "%s %s: %s %s=0x%lx, %s=0x%lx, %s=0x%lx %s=0x%x",
2203 (pcmu_p->pcmu_pcbm_p)->pcbm_nameinst_str,
2204 (pcmu_p->pcmu_pcbm_p)->pcbm_nameaddr_str,
2205 aux_msg,
2206 PCI_PBM_AFAR, pbm_err->pbm_afar,
2207 PCI_PBM_AFSR, pbm_err->pbm_afsr,
2208 PCI_PBM_CSR, pbm_err->pbm_ctl_stat,
2209 "portid", pcmu_p->pcmu_id);