1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1990-2002 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/conf.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/ddi_impldefs.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/async.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/sysiosbus.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/sysioerr.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/x_call.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/machsystm.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/vmsystm.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/cpu_module.h> 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* 45*7c478bd9Sstevel@tonic-gate * Set the following variable in /etc/system to tell the kernel 46*7c478bd9Sstevel@tonic-gate * not to shutdown the machine if the temperature reaches 47*7c478bd9Sstevel@tonic-gate * the Thermal Warning limit. 48*7c478bd9Sstevel@tonic-gate */ 49*7c478bd9Sstevel@tonic-gate int oven_test = 0; 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate /* 52*7c478bd9Sstevel@tonic-gate * To indicate if the prom has the property of "thermal-interrupt". 53*7c478bd9Sstevel@tonic-gate */ 54*7c478bd9Sstevel@tonic-gate static int thermal_interrupt_enabled = 0; 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate #ifdef _STARFIRE 57*7c478bd9Sstevel@tonic-gate #include <sys/starfire.h> 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate int 60*7c478bd9Sstevel@tonic-gate pc_translate_tgtid(caddr_t, int, volatile uint64_t *); 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate void 63*7c478bd9Sstevel@tonic-gate pc_ittrans_cleanup(caddr_t, volatile uint64_t *); 64*7c478bd9Sstevel@tonic-gate #endif /* _STARFIRE */ 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate /* 67*7c478bd9Sstevel@tonic-gate * adb debug_sysio_errs to 1 if you don't want your system to panic on 68*7c478bd9Sstevel@tonic-gate * sbus ue errors. adb sysio_err_flag to 0 if you don't want your system 69*7c478bd9Sstevel@tonic-gate * to check for sysio errors at all. 70*7c478bd9Sstevel@tonic-gate */ 71*7c478bd9Sstevel@tonic-gate int sysio_err_flag = 1; 72*7c478bd9Sstevel@tonic-gate uint_t debug_sysio_errs = 0; 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate /* 75*7c478bd9Sstevel@tonic-gate * bto_cnt = number of bus errors and timeouts allowed within bto_secs 76*7c478bd9Sstevel@tonic-gate * use /etc/system to change the bto_cnt to a very large number if 77*7c478bd9Sstevel@tonic-gate * it's a problem! 78*7c478bd9Sstevel@tonic-gate */ 79*7c478bd9Sstevel@tonic-gate int bto_secs = 10; 80*7c478bd9Sstevel@tonic-gate int bto_cnt = 10; 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate static uint_t 83*7c478bd9Sstevel@tonic-gate sysio_ue_intr(struct sbus_soft_state *softsp); 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate static uint_t 86*7c478bd9Sstevel@tonic-gate sysio_ce_intr(struct sbus_soft_state *softsp); 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate static uint_t 89*7c478bd9Sstevel@tonic-gate sbus_err_intr(struct sbus_soft_state *softsp); 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate static void 92*7c478bd9Sstevel@tonic-gate sysio_log_ce_err(struct async_flt *ecc, char *unum); 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate static void 95*7c478bd9Sstevel@tonic-gate sysio_log_ue_err(struct async_flt *ecc, char *unum); 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate static void 98*7c478bd9Sstevel@tonic-gate sbus_clear_intr(struct sbus_soft_state *softsp, uint64_t *pafsr); 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate static void 101*7c478bd9Sstevel@tonic-gate sbus_log_error(struct sbus_soft_state *softsp, uint64_t *pafsr, uint64_t *pafar, 102*7c478bd9Sstevel@tonic-gate ushort_t id, ushort_t inst, int cleared, 103*7c478bd9Sstevel@tonic-gate on_trap_data_t *ontrap_data); 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate static int 106*7c478bd9Sstevel@tonic-gate sbus_check_bto(struct sbus_soft_state *softsp); 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate static void 109*7c478bd9Sstevel@tonic-gate sbus_log_csr_error(struct async_flt *aflt, char *unum); 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate static uint_t 112*7c478bd9Sstevel@tonic-gate sbus_ctrl_ecc_err(struct sbus_soft_state *softsp); 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate static uint_t 115*7c478bd9Sstevel@tonic-gate sysio_dis_err(struct sbus_soft_state *softsp); 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate static uint_t 118*7c478bd9Sstevel@tonic-gate sysio_init_err(struct sbus_soft_state *softsp); 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate static uint_t 121*7c478bd9Sstevel@tonic-gate sysio_thermal_warn_intr(struct sbus_soft_state *softsp); 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate static int sbus_pil[] = {SBUS_UE_PIL, SBUS_CE_PIL, SBUS_ERR_PIL, SBUS_PF_PIL, 124*7c478bd9Sstevel@tonic-gate SBUS_THERMAL_PIL, SBUS_PM_PIL}; 125*7c478bd9Sstevel@tonic-gate int 126*7c478bd9Sstevel@tonic-gate sysio_err_init(struct sbus_soft_state *softsp, caddr_t address) 127*7c478bd9Sstevel@tonic-gate { 128*7c478bd9Sstevel@tonic-gate if (sysio_err_flag == 0) { 129*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Warning: sysio errors not initialized\n"); 130*7c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 131*7c478bd9Sstevel@tonic-gate } 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate /* 134*7c478bd9Sstevel@tonic-gate * Get the address of the already mapped-in sysio/sbus error registers. 135*7c478bd9Sstevel@tonic-gate * Simply add each registers offset to the already mapped in address 136*7c478bd9Sstevel@tonic-gate * that was retrieved from the device node's "address" property, 137*7c478bd9Sstevel@tonic-gate * and passed as an argument to this function. 138*7c478bd9Sstevel@tonic-gate * 139*7c478bd9Sstevel@tonic-gate * Define a macro for the pointer arithmetic ... 140*7c478bd9Sstevel@tonic-gate */ 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate #define REG_ADDR(b, o) (uint64_t *)((caddr_t)(b) + (o)) 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate softsp->sysio_ecc_reg = REG_ADDR(address, OFF_SYSIO_ECC_REGS); 145*7c478bd9Sstevel@tonic-gate softsp->sysio_ue_reg = REG_ADDR(address, OFF_SYSIO_UE_REGS); 146*7c478bd9Sstevel@tonic-gate softsp->sysio_ce_reg = REG_ADDR(address, OFF_SYSIO_CE_REGS); 147*7c478bd9Sstevel@tonic-gate softsp->sbus_err_reg = REG_ADDR(address, OFF_SBUS_ERR_REGS); 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate #undef REG_ADDR 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate /* 152*7c478bd9Sstevel@tonic-gate * create the interrupt-priorities property if it doesn't 153*7c478bd9Sstevel@tonic-gate * already exist to provide a hint as to the PIL level for 154*7c478bd9Sstevel@tonic-gate * our interrupt. 155*7c478bd9Sstevel@tonic-gate */ 156*7c478bd9Sstevel@tonic-gate { 157*7c478bd9Sstevel@tonic-gate int len; 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate if (ddi_getproplen(DDI_DEV_T_ANY, softsp->dip, 160*7c478bd9Sstevel@tonic-gate DDI_PROP_DONTPASS, "interrupt-priorities", 161*7c478bd9Sstevel@tonic-gate &len) != DDI_PROP_SUCCESS) { 162*7c478bd9Sstevel@tonic-gate /* Create the interrupt-priorities property. */ 163*7c478bd9Sstevel@tonic-gate (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 164*7c478bd9Sstevel@tonic-gate softsp->dip, "interrupt-priorities", 165*7c478bd9Sstevel@tonic-gate (int *)sbus_pil, sizeof (sbus_pil) / sizeof (int)); 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate (void) ddi_add_intr(softsp->dip, 0, NULL, NULL, 170*7c478bd9Sstevel@tonic-gate (uint_t (*)())sysio_ue_intr, (caddr_t)softsp); 171*7c478bd9Sstevel@tonic-gate (void) ddi_add_intr(softsp->dip, 1, NULL, NULL, 172*7c478bd9Sstevel@tonic-gate (uint_t (*)())sysio_ce_intr, (caddr_t)softsp); 173*7c478bd9Sstevel@tonic-gate (void) ddi_add_intr(softsp->dip, 2, NULL, NULL, 174*7c478bd9Sstevel@tonic-gate (uint_t (*)())sbus_err_intr, (caddr_t)softsp); 175*7c478bd9Sstevel@tonic-gate /* 176*7c478bd9Sstevel@tonic-gate * If the thermal-interrupt property is in place, 177*7c478bd9Sstevel@tonic-gate * then register the thermal warning interrupt handler and 178*7c478bd9Sstevel@tonic-gate * program its mapping register 179*7c478bd9Sstevel@tonic-gate */ 180*7c478bd9Sstevel@tonic-gate thermal_interrupt_enabled = ddi_getprop(DDI_DEV_T_ANY, softsp->dip, 181*7c478bd9Sstevel@tonic-gate DDI_PROP_DONTPASS, "thermal-interrupt", -1); 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate if (thermal_interrupt_enabled == 1) { 184*7c478bd9Sstevel@tonic-gate (void) ddi_add_intr(softsp->dip, 4, NULL, NULL, 185*7c478bd9Sstevel@tonic-gate (uint_t (*)())sysio_thermal_warn_intr, (caddr_t)softsp); 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate bus_func_register(BF_TYPE_UE, (busfunc_t)sbus_ctrl_ecc_err, softsp); 189*7c478bd9Sstevel@tonic-gate bus_func_register(BF_TYPE_ERRDIS, (busfunc_t)sysio_dis_err, softsp); 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate (void) sysio_init_err(softsp); 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate int 197*7c478bd9Sstevel@tonic-gate sysio_err_resume_init(struct sbus_soft_state *softsp) 198*7c478bd9Sstevel@tonic-gate { 199*7c478bd9Sstevel@tonic-gate (void) sysio_init_err(softsp); 200*7c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate int 204*7c478bd9Sstevel@tonic-gate sysio_err_uninit(struct sbus_soft_state *softsp) 205*7c478bd9Sstevel@tonic-gate { 206*7c478bd9Sstevel@tonic-gate /* remove the interrupts from the interrupt list */ 207*7c478bd9Sstevel@tonic-gate (void) sysio_dis_err(softsp); 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate ddi_remove_intr(softsp->dip, 0, NULL); 210*7c478bd9Sstevel@tonic-gate ddi_remove_intr(softsp->dip, 1, NULL); 211*7c478bd9Sstevel@tonic-gate ddi_remove_intr(softsp->dip, 2, NULL); 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate if (thermal_interrupt_enabled == 1) { 214*7c478bd9Sstevel@tonic-gate ddi_remove_intr(softsp->dip, 4, NULL); 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate bus_func_unregister(BF_TYPE_UE, (busfunc_t)sbus_ctrl_ecc_err, softsp); 218*7c478bd9Sstevel@tonic-gate bus_func_unregister(BF_TYPE_ERRDIS, (busfunc_t)sysio_dis_err, softsp); 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate static uint_t 224*7c478bd9Sstevel@tonic-gate sysio_init_err(struct sbus_soft_state *softsp) 225*7c478bd9Sstevel@tonic-gate { 226*7c478bd9Sstevel@tonic-gate volatile uint64_t tmp_mondo_vec, tmpreg; 227*7c478bd9Sstevel@tonic-gate volatile uint64_t *mondo_vec_reg; 228*7c478bd9Sstevel@tonic-gate uint_t cpu_id, acpu_id; 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate acpu_id = intr_dist_cpuid(); 231*7c478bd9Sstevel@tonic-gate /* 232*7c478bd9Sstevel@tonic-gate * Program the mondo vector accordingly. This MUST be the 233*7c478bd9Sstevel@tonic-gate * last thing we do. Once we program the mondo, the device 234*7c478bd9Sstevel@tonic-gate * may begin to interrupt. Store it in the hardware reg. 235*7c478bd9Sstevel@tonic-gate */ 236*7c478bd9Sstevel@tonic-gate mondo_vec_reg = (uint64_t *)(softsp->intr_mapping_reg + UE_ECC_MAPREG); 237*7c478bd9Sstevel@tonic-gate cpu_id = acpu_id; 238*7c478bd9Sstevel@tonic-gate #ifdef _STARFIRE 239*7c478bd9Sstevel@tonic-gate cpu_id = pc_translate_tgtid(softsp->ittrans_cookie, cpu_id, 240*7c478bd9Sstevel@tonic-gate mondo_vec_reg); 241*7c478bd9Sstevel@tonic-gate #endif /* _STARFIRE */ 242*7c478bd9Sstevel@tonic-gate tmp_mondo_vec = (cpu_id << INTERRUPT_CPU_FIELD) | INTERRUPT_VALID; 243*7c478bd9Sstevel@tonic-gate *mondo_vec_reg = tmp_mondo_vec; 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate mondo_vec_reg = (uint64_t *)(softsp->intr_mapping_reg + CE_ECC_MAPREG); 246*7c478bd9Sstevel@tonic-gate cpu_id = acpu_id; 247*7c478bd9Sstevel@tonic-gate #ifdef _STARFIRE 248*7c478bd9Sstevel@tonic-gate cpu_id = pc_translate_tgtid(softsp->ittrans_cookie, cpu_id, 249*7c478bd9Sstevel@tonic-gate mondo_vec_reg); 250*7c478bd9Sstevel@tonic-gate #endif /* _STARFIRE */ 251*7c478bd9Sstevel@tonic-gate tmp_mondo_vec = (cpu_id << INTERRUPT_CPU_FIELD) | INTERRUPT_VALID; 252*7c478bd9Sstevel@tonic-gate *mondo_vec_reg = tmp_mondo_vec; 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate mondo_vec_reg = 255*7c478bd9Sstevel@tonic-gate (uint64_t *)(softsp->intr_mapping_reg + SBUS_ERR_MAPREG); 256*7c478bd9Sstevel@tonic-gate cpu_id = acpu_id; 257*7c478bd9Sstevel@tonic-gate #ifdef _STARFIRE 258*7c478bd9Sstevel@tonic-gate cpu_id = pc_translate_tgtid(softsp->ittrans_cookie, cpu_id, 259*7c478bd9Sstevel@tonic-gate mondo_vec_reg); 260*7c478bd9Sstevel@tonic-gate #endif /* _STARFIRE */ 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate tmp_mondo_vec = (cpu_id << INTERRUPT_CPU_FIELD) | INTERRUPT_VALID; 263*7c478bd9Sstevel@tonic-gate *mondo_vec_reg = tmp_mondo_vec; 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate if (thermal_interrupt_enabled == 1) { 266*7c478bd9Sstevel@tonic-gate mondo_vec_reg = (softsp->intr_mapping_reg + THERMAL_MAPREG); 267*7c478bd9Sstevel@tonic-gate cpu_id = acpu_id; 268*7c478bd9Sstevel@tonic-gate tmp_mondo_vec = (cpu_id << INTERRUPT_CPU_FIELD) | 269*7c478bd9Sstevel@tonic-gate INTERRUPT_VALID; 270*7c478bd9Sstevel@tonic-gate *mondo_vec_reg = tmp_mondo_vec; 271*7c478bd9Sstevel@tonic-gate } 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate /* Flush store buffers */ 274*7c478bd9Sstevel@tonic-gate tmpreg = *softsp->sbus_ctrl_reg; 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate /* 277*7c478bd9Sstevel@tonic-gate * XXX - This may already be set by the OBP. 278*7c478bd9Sstevel@tonic-gate */ 279*7c478bd9Sstevel@tonic-gate tmpreg = SYSIO_APCKEN; 280*7c478bd9Sstevel@tonic-gate *softsp->sysio_ctrl_reg |= tmpreg; 281*7c478bd9Sstevel@tonic-gate tmpreg = (SECR_ECC_EN | SECR_UE_INTEN | SECR_CE_INTEN); 282*7c478bd9Sstevel@tonic-gate *softsp->sysio_ecc_reg = tmpreg; 283*7c478bd9Sstevel@tonic-gate tmpreg = SB_CSR_ERRINT_EN; 284*7c478bd9Sstevel@tonic-gate *softsp->sbus_err_reg |= tmpreg; 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate /* Initialize timeout/bus error counter */ 287*7c478bd9Sstevel@tonic-gate softsp->bto_timestamp = 0; 288*7c478bd9Sstevel@tonic-gate softsp->bto_ctr = 0; 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate return (0); 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate static uint_t 294*7c478bd9Sstevel@tonic-gate sysio_dis_err(struct sbus_soft_state *softsp) 295*7c478bd9Sstevel@tonic-gate { 296*7c478bd9Sstevel@tonic-gate volatile uint64_t tmpreg; 297*7c478bd9Sstevel@tonic-gate volatile uint64_t *mondo_vec_reg, *clear_vec_reg; 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate *softsp->sysio_ctrl_reg &= ~SYSIO_APCKEN; 300*7c478bd9Sstevel@tonic-gate *softsp->sysio_ecc_reg = 0; 301*7c478bd9Sstevel@tonic-gate *softsp->sbus_err_reg &= ~SB_CSR_ERRINT_EN; 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate /* Flush store buffers */ 304*7c478bd9Sstevel@tonic-gate tmpreg = *softsp->sbus_ctrl_reg; 305*7c478bd9Sstevel@tonic-gate #ifdef lint 306*7c478bd9Sstevel@tonic-gate tmpreg = tmpreg; 307*7c478bd9Sstevel@tonic-gate #endif 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate /* Unmap mapping registers */ 310*7c478bd9Sstevel@tonic-gate mondo_vec_reg = (softsp->intr_mapping_reg + UE_ECC_MAPREG); 311*7c478bd9Sstevel@tonic-gate clear_vec_reg = (softsp->clr_intr_reg + UE_ECC_CLEAR); 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate *mondo_vec_reg = 0; 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate #ifdef _STARFIRE 316*7c478bd9Sstevel@tonic-gate /* do cleanup for starfire interrupt target translation */ 317*7c478bd9Sstevel@tonic-gate pc_ittrans_cleanup(softsp->ittrans_cookie, mondo_vec_reg); 318*7c478bd9Sstevel@tonic-gate #endif /* _STARFIRE */ 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate *clear_vec_reg = 0; 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate mondo_vec_reg = (softsp->intr_mapping_reg + CE_ECC_MAPREG); 323*7c478bd9Sstevel@tonic-gate clear_vec_reg = (softsp->clr_intr_reg + CE_ECC_CLEAR); 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate *mondo_vec_reg = 0; 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate #ifdef _STARFIRE 328*7c478bd9Sstevel@tonic-gate /* Do cleanup for starfire interrupt target translation */ 329*7c478bd9Sstevel@tonic-gate pc_ittrans_cleanup(softsp->ittrans_cookie, mondo_vec_reg); 330*7c478bd9Sstevel@tonic-gate #endif /* _STARFIRE */ 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate *clear_vec_reg = 0; 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate mondo_vec_reg = (softsp->intr_mapping_reg + SBUS_ERR_MAPREG); 335*7c478bd9Sstevel@tonic-gate clear_vec_reg = (softsp->clr_intr_reg + SBUS_ERR_CLEAR); 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate *mondo_vec_reg = 0; 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate #ifdef _STARFIRE 340*7c478bd9Sstevel@tonic-gate /* Do cleanup for starfire interrupt target translation */ 341*7c478bd9Sstevel@tonic-gate pc_ittrans_cleanup(softsp->ittrans_cookie, mondo_vec_reg); 342*7c478bd9Sstevel@tonic-gate #endif /* _STARFIRE */ 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate *clear_vec_reg = 0; 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate /* Flush store buffers */ 347*7c478bd9Sstevel@tonic-gate tmpreg = *softsp->sbus_ctrl_reg; 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate return (BF_NONE); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate /* 353*7c478bd9Sstevel@tonic-gate * Gather information about the error into an async_flt structure, and then 354*7c478bd9Sstevel@tonic-gate * enqueue the error for reporting and processing and panic. 355*7c478bd9Sstevel@tonic-gate */ 356*7c478bd9Sstevel@tonic-gate static uint_t 357*7c478bd9Sstevel@tonic-gate sysio_ue_intr(struct sbus_soft_state *softsp) 358*7c478bd9Sstevel@tonic-gate { 359*7c478bd9Sstevel@tonic-gate volatile uint64_t t_afsr; 360*7c478bd9Sstevel@tonic-gate volatile uint64_t t_afar; 361*7c478bd9Sstevel@tonic-gate volatile uint64_t *ue_reg, *afar_reg, *clear_reg; 362*7c478bd9Sstevel@tonic-gate struct async_flt ecc; 363*7c478bd9Sstevel@tonic-gate uint64_t offset; 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate /* 366*7c478bd9Sstevel@tonic-gate * Disable all further sbus errors, for this sbus instance, for 367*7c478bd9Sstevel@tonic-gate * what is guaranteed to be a fatal error. And grab any other cpus. 368*7c478bd9Sstevel@tonic-gate */ 369*7c478bd9Sstevel@tonic-gate (void) sysio_dis_err(softsp); /* disabled sysio errors */ 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate /* 372*7c478bd9Sstevel@tonic-gate * Then read and clear the afsr/afar and clear interrupt regs. 373*7c478bd9Sstevel@tonic-gate */ 374*7c478bd9Sstevel@tonic-gate ue_reg = (uint64_t *)softsp->sysio_ue_reg; 375*7c478bd9Sstevel@tonic-gate t_afsr = *ue_reg; 376*7c478bd9Sstevel@tonic-gate afar_reg = (uint64_t *)ue_reg + 1; 377*7c478bd9Sstevel@tonic-gate t_afar = *afar_reg; 378*7c478bd9Sstevel@tonic-gate *ue_reg = t_afsr; 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate clear_reg = (softsp->clr_intr_reg + UE_ECC_CLEAR); 381*7c478bd9Sstevel@tonic-gate *clear_reg = 0; 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate /* 384*7c478bd9Sstevel@tonic-gate * The AFSR DW_OFFSET field contains the offset of the doubleword with 385*7c478bd9Sstevel@tonic-gate * the ECC error relative to the 64-byte aligned PA. We multiply by 8 386*7c478bd9Sstevel@tonic-gate * to convert to a byte offset, and then add this to flt_addr. 387*7c478bd9Sstevel@tonic-gate */ 388*7c478bd9Sstevel@tonic-gate offset = ((t_afsr & SB_UE_AFSR_OFF) >> SB_UE_DW_SHIFT) * 8; 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate bzero(&ecc, sizeof (ecc)); 391*7c478bd9Sstevel@tonic-gate ecc.flt_id = gethrtime(); 392*7c478bd9Sstevel@tonic-gate ecc.flt_stat = t_afsr; 393*7c478bd9Sstevel@tonic-gate ecc.flt_addr = P2ALIGN(t_afar, 64) + offset; 394*7c478bd9Sstevel@tonic-gate ecc.flt_func = sysio_log_ue_err; 395*7c478bd9Sstevel@tonic-gate ecc.flt_bus_id = softsp->upa_id; 396*7c478bd9Sstevel@tonic-gate ecc.flt_inst = ddi_get_instance(softsp->dip); 397*7c478bd9Sstevel@tonic-gate ecc.flt_status = ECC_IOBUS; 398*7c478bd9Sstevel@tonic-gate ecc.flt_in_memory = (pf_is_memory(t_afar >> MMU_PAGESHIFT)) ? 1: 0; 399*7c478bd9Sstevel@tonic-gate ecc.flt_class = BUS_FAULT; 400*7c478bd9Sstevel@tonic-gate ecc.flt_panic = (debug_sysio_errs == 0); 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate errorq_dispatch(ue_queue, &ecc, sizeof (ecc), ecc.flt_panic); 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate /* 405*7c478bd9Sstevel@tonic-gate * If the UE is in memory and fatal, save the fault info so the 406*7c478bd9Sstevel@tonic-gate * panic code will know to check for copyback errors. 407*7c478bd9Sstevel@tonic-gate */ 408*7c478bd9Sstevel@tonic-gate if (ecc.flt_panic && ecc.flt_in_memory) 409*7c478bd9Sstevel@tonic-gate panic_aflt = ecc; 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate /* 412*7c478bd9Sstevel@tonic-gate * We must also check for other bus UE errors, and panic if 413*7c478bd9Sstevel@tonic-gate * any fatal ones are detected at this point. 414*7c478bd9Sstevel@tonic-gate */ 415*7c478bd9Sstevel@tonic-gate if (bus_func_invoke(BF_TYPE_UE) == BF_FATAL) 416*7c478bd9Sstevel@tonic-gate ecc.flt_panic = 1; 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate if (ecc.flt_panic) 419*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "Fatal Sbus%d UE Error", ecc.flt_inst); 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate return (DDI_INTR_CLAIMED); 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate /* 425*7c478bd9Sstevel@tonic-gate * callback logging function from the common error handling code 426*7c478bd9Sstevel@tonic-gate */ 427*7c478bd9Sstevel@tonic-gate static void 428*7c478bd9Sstevel@tonic-gate sysio_log_ue_err(struct async_flt *ecc, char *unum) 429*7c478bd9Sstevel@tonic-gate { 430*7c478bd9Sstevel@tonic-gate uint64_t t_afsr = ecc->flt_stat; 431*7c478bd9Sstevel@tonic-gate uint64_t t_afar = ecc->flt_addr; 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate ushort_t id = ecc->flt_bus_id; 434*7c478bd9Sstevel@tonic-gate ushort_t inst = ecc->flt_inst; 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_UE_AFSR_P_PIO) { 437*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "SBus%d UE Primary Error from PIO: " 438*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x Id %d", 439*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 440*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, id); 441*7c478bd9Sstevel@tonic-gate } 442*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_UE_AFSR_P_DRD) { 443*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "SBus%d UE Primary Error DMA read: " 444*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s Id %d", 445*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 446*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_UE_AFSR_P_DWR) { 449*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "SBus%d UE Primary Error DVMA write: " 450*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s Id %d", 451*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 452*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate /* 455*7c478bd9Sstevel@tonic-gate * We should never hit the secondary error panics. 456*7c478bd9Sstevel@tonic-gate */ 457*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_UE_AFSR_S_PIO) { 458*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "SBus%d UE Secondary Error from PIO: " 459*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x Id %d", 460*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 461*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, id); 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_UE_AFSR_S_DRD) { 464*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "SBus%d UE Secondary Error DMA read: " 465*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s Id %d", 466*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 467*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_UE_AFSR_S_DWR) { 470*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "SBus%d UE Secondary Error DMA write: " 471*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s Id %d", 472*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 473*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate if ((debug_sysio_errs) || (aft_verbose)) { 477*7c478bd9Sstevel@tonic-gate (void) read_ecc_data(ecc, 1, 0); 478*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "\tOffset 0x%x, Size %d, UPA MID 0x%x\n", 479*7c478bd9Sstevel@tonic-gate (uint32_t)((t_afsr & SB_UE_AFSR_OFF) >> SB_UE_DW_SHIFT), 480*7c478bd9Sstevel@tonic-gate (uint32_t)((t_afsr & SB_UE_AFSR_SIZE) >> SB_UE_SIZE_SHIFT), 481*7c478bd9Sstevel@tonic-gate (uint32_t)((t_afsr & SB_UE_AFSR_MID) >> SB_UE_MID_SHIFT)); 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate } 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate /* 486*7c478bd9Sstevel@tonic-gate * gather the information about the error, plus a pointer to 487*7c478bd9Sstevel@tonic-gate * the callback logging function, and call the generic ce_error handler. 488*7c478bd9Sstevel@tonic-gate */ 489*7c478bd9Sstevel@tonic-gate static uint_t 490*7c478bd9Sstevel@tonic-gate sysio_ce_intr(struct sbus_soft_state *softsp) 491*7c478bd9Sstevel@tonic-gate { 492*7c478bd9Sstevel@tonic-gate volatile uint64_t t_afsr; 493*7c478bd9Sstevel@tonic-gate volatile uint64_t t_afar; 494*7c478bd9Sstevel@tonic-gate volatile uint64_t *afar_reg, *clear_reg, *ce_reg; 495*7c478bd9Sstevel@tonic-gate struct async_flt ecc; 496*7c478bd9Sstevel@tonic-gate uint64_t offset; 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate ce_reg = (uint64_t *)softsp->sysio_ce_reg; 499*7c478bd9Sstevel@tonic-gate t_afsr = *ce_reg; 500*7c478bd9Sstevel@tonic-gate afar_reg = (uint64_t *)ce_reg + 1; 501*7c478bd9Sstevel@tonic-gate t_afar = *afar_reg; 502*7c478bd9Sstevel@tonic-gate *ce_reg = t_afsr; 503*7c478bd9Sstevel@tonic-gate 504*7c478bd9Sstevel@tonic-gate clear_reg = (softsp->clr_intr_reg + CE_ECC_CLEAR); 505*7c478bd9Sstevel@tonic-gate *clear_reg = 0; 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate /* 508*7c478bd9Sstevel@tonic-gate * The AFSR DW_OFFSET field contains the offset of the doubleword with 509*7c478bd9Sstevel@tonic-gate * the ECC error relative to the 64-byte aligned PA. We multiply by 8 510*7c478bd9Sstevel@tonic-gate * to convert to a byte offset, and then add this to flt_addr. 511*7c478bd9Sstevel@tonic-gate */ 512*7c478bd9Sstevel@tonic-gate offset = ((t_afsr & SB_UE_AFSR_OFF) >> SB_UE_DW_SHIFT) * 8; 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate bzero(&ecc, sizeof (ecc)); 515*7c478bd9Sstevel@tonic-gate ecc.flt_id = gethrtime(); 516*7c478bd9Sstevel@tonic-gate ecc.flt_stat = t_afsr; 517*7c478bd9Sstevel@tonic-gate ecc.flt_addr = P2ALIGN(t_afar, 64) + offset; 518*7c478bd9Sstevel@tonic-gate ecc.flt_func = sysio_log_ce_err; 519*7c478bd9Sstevel@tonic-gate ecc.flt_bus_id = softsp->upa_id; 520*7c478bd9Sstevel@tonic-gate ecc.flt_inst = ddi_get_instance(softsp->dip); 521*7c478bd9Sstevel@tonic-gate ecc.flt_status = ECC_IOBUS; 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate ecc.flt_synd = (ushort_t)((t_afsr & SB_CE_AFSR_SYND) >> 524*7c478bd9Sstevel@tonic-gate SB_CE_SYND_SHIFT); 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate ecc.flt_in_memory = (pf_is_memory(t_afar >> MMU_PAGESHIFT)) ? 1: 0; 527*7c478bd9Sstevel@tonic-gate ecc.flt_class = BUS_FAULT; 528*7c478bd9Sstevel@tonic-gate 529*7c478bd9Sstevel@tonic-gate ce_scrub(&ecc); 530*7c478bd9Sstevel@tonic-gate errorq_dispatch(ce_queue, &ecc, sizeof (ecc), ERRORQ_ASYNC); 531*7c478bd9Sstevel@tonic-gate 532*7c478bd9Sstevel@tonic-gate return (DDI_INTR_CLAIMED); 533*7c478bd9Sstevel@tonic-gate } 534*7c478bd9Sstevel@tonic-gate 535*7c478bd9Sstevel@tonic-gate /* 536*7c478bd9Sstevel@tonic-gate * callback logging function from the common error handling code 537*7c478bd9Sstevel@tonic-gate */ 538*7c478bd9Sstevel@tonic-gate static void 539*7c478bd9Sstevel@tonic-gate sysio_log_ce_err(struct async_flt *ecc, char *unum) 540*7c478bd9Sstevel@tonic-gate { 541*7c478bd9Sstevel@tonic-gate uint64_t t_afsr = ecc->flt_stat; 542*7c478bd9Sstevel@tonic-gate uint64_t t_afar = ecc->flt_addr; 543*7c478bd9Sstevel@tonic-gate ushort_t id = ecc->flt_bus_id; 544*7c478bd9Sstevel@tonic-gate ushort_t inst = ecc->flt_inst; 545*7c478bd9Sstevel@tonic-gate int ce_verbose = ce_verbose_memory; 546*7c478bd9Sstevel@tonic-gate char *syndrome_str = "!\tSyndrome 0x%x, Offset 0x%x, Size %d, " 547*7c478bd9Sstevel@tonic-gate "UPA MID 0x%x\n"; 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate if ((!ce_verbose_memory) && (!debug_sysio_errs)) 550*7c478bd9Sstevel@tonic-gate return; 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_CE_AFSR_P_PIO) { 553*7c478bd9Sstevel@tonic-gate char *fmtstr = "!SBus%d CE Primary Error from PIO: " 554*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x Id %d\n"; 555*7c478bd9Sstevel@tonic-gate 556*7c478bd9Sstevel@tonic-gate if ((debug_sysio_errs) || (ce_verbose > 1)) 557*7c478bd9Sstevel@tonic-gate fmtstr++; 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, fmtstr, inst, (uint32_t)(t_afsr>>32), 560*7c478bd9Sstevel@tonic-gate (uint32_t)t_afsr, (uint32_t)(t_afar>>32), 561*7c478bd9Sstevel@tonic-gate (uint32_t)t_afar, id); 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_CE_AFSR_P_DRD) { 564*7c478bd9Sstevel@tonic-gate char *fmtstr = "!SBus%d CE Primary Error DMA read: " 565*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s " 566*7c478bd9Sstevel@tonic-gate "Id %d\n"; 567*7c478bd9Sstevel@tonic-gate 568*7c478bd9Sstevel@tonic-gate if ((debug_sysio_errs) || (ce_verbose > 1)) 569*7c478bd9Sstevel@tonic-gate fmtstr++; 570*7c478bd9Sstevel@tonic-gate 571*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, fmtstr, inst, (uint32_t)(t_afsr>>32), 572*7c478bd9Sstevel@tonic-gate (uint32_t)t_afsr, (uint32_t)(t_afar>>32), (uint32_t)t_afar, 573*7c478bd9Sstevel@tonic-gate unum, id); 574*7c478bd9Sstevel@tonic-gate } 575*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_CE_AFSR_P_DWR) { 576*7c478bd9Sstevel@tonic-gate char *fmtstr = "!SBus%d CE Primary Error DMA write: " 577*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s Id %d\n"; 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate if ((debug_sysio_errs) || (ce_verbose > 1)) 580*7c478bd9Sstevel@tonic-gate fmtstr++; 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, fmtstr, inst, (uint32_t)(t_afsr>>32), 583*7c478bd9Sstevel@tonic-gate (uint32_t)t_afsr, (uint32_t)(t_afar>>32), (uint32_t)t_afar, 584*7c478bd9Sstevel@tonic-gate unum, id); 585*7c478bd9Sstevel@tonic-gate } 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_CE_AFSR_S_PIO) { 588*7c478bd9Sstevel@tonic-gate char *fmtstr = "!SBus%d CE Secondary Error from PIO: " 589*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x Id %d\n"; 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate if ((debug_sysio_errs) || (ce_verbose > 1)) 592*7c478bd9Sstevel@tonic-gate fmtstr++; 593*7c478bd9Sstevel@tonic-gate 594*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, fmtstr, inst, (uint32_t)(t_afsr>>32), 595*7c478bd9Sstevel@tonic-gate (uint32_t)t_afsr, (uint32_t)(t_afar>>32), (uint32_t)t_afar, 596*7c478bd9Sstevel@tonic-gate id); 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_CE_AFSR_S_DRD) { 599*7c478bd9Sstevel@tonic-gate char *fmtstr = "!SBus%d CE Secondary Error DMA read: " 600*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s " 601*7c478bd9Sstevel@tonic-gate "Id %d\n"; 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate if ((debug_sysio_errs) || (ce_verbose > 1)) 604*7c478bd9Sstevel@tonic-gate fmtstr++; 605*7c478bd9Sstevel@tonic-gate 606*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, fmtstr, inst, (uint32_t)(t_afsr>>32), 607*7c478bd9Sstevel@tonic-gate (uint32_t)t_afsr, (uint32_t)(t_afar>>32), (uint32_t)t_afar, 608*7c478bd9Sstevel@tonic-gate unum, id); 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_CE_AFSR_S_DWR) { 611*7c478bd9Sstevel@tonic-gate char *fmtstr = "!SBus%d CE Secondary Error DMA write: " 612*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s " 613*7c478bd9Sstevel@tonic-gate "Id %d\n"; 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate if ((debug_sysio_errs) || (ce_verbose > 1)) 616*7c478bd9Sstevel@tonic-gate fmtstr++; 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, fmtstr, 619*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 620*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); 621*7c478bd9Sstevel@tonic-gate } 622*7c478bd9Sstevel@tonic-gate 623*7c478bd9Sstevel@tonic-gate if ((debug_sysio_errs) || (ce_verbose > 1)) 624*7c478bd9Sstevel@tonic-gate syndrome_str++; 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, syndrome_str, 627*7c478bd9Sstevel@tonic-gate (uint32_t)((t_afsr & SB_CE_AFSR_SYND) >> SB_CE_SYND_SHIFT), 628*7c478bd9Sstevel@tonic-gate (uint32_t)((t_afsr & SB_CE_AFSR_OFF) >> SB_CE_OFFSET_SHIFT), 629*7c478bd9Sstevel@tonic-gate (uint32_t)((t_afsr & SB_CE_AFSR_SIZE) >> SB_CE_SIZE_SHIFT), 630*7c478bd9Sstevel@tonic-gate (uint32_t)((t_afsr & SB_CE_AFSR_MID) >> SB_CE_MID_SHIFT)); 631*7c478bd9Sstevel@tonic-gate } 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate static uint_t 634*7c478bd9Sstevel@tonic-gate sbus_err_intr(struct sbus_soft_state *softsp) 635*7c478bd9Sstevel@tonic-gate { 636*7c478bd9Sstevel@tonic-gate volatile uint64_t t_afsr; 637*7c478bd9Sstevel@tonic-gate volatile uint64_t t_afar; 638*7c478bd9Sstevel@tonic-gate ushort_t id, inst; 639*7c478bd9Sstevel@tonic-gate int cleared = 0; 640*7c478bd9Sstevel@tonic-gate volatile uint64_t *afar_reg; 641*7c478bd9Sstevel@tonic-gate on_trap_data_t *otp = softsp->ontrap_data; 642*7c478bd9Sstevel@tonic-gate 643*7c478bd9Sstevel@tonic-gate t_afsr = *softsp->sbus_err_reg; 644*7c478bd9Sstevel@tonic-gate afar_reg = (uint64_t *)softsp->sbus_err_reg + 1; 645*7c478bd9Sstevel@tonic-gate t_afar = *afar_reg; 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate if (otp == NULL || !(otp->ot_prot & OT_DATA_ACCESS)) { 648*7c478bd9Sstevel@tonic-gate sbus_clear_intr(softsp, (uint64_t *)&t_afsr); 649*7c478bd9Sstevel@tonic-gate cleared = 1; 650*7c478bd9Sstevel@tonic-gate } 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate id = (ushort_t)softsp->upa_id; 653*7c478bd9Sstevel@tonic-gate inst = (ushort_t)ddi_get_instance(softsp->dip); 654*7c478bd9Sstevel@tonic-gate 655*7c478bd9Sstevel@tonic-gate if (debug_sysio_errs) { 656*7c478bd9Sstevel@tonic-gate if (otp != NULL && (otp->ot_prot & OT_DATA_ACCESS)) 657*7c478bd9Sstevel@tonic-gate otp->ot_trap |= OT_DATA_ACCESS; 658*7c478bd9Sstevel@tonic-gate if (!cleared) 659*7c478bd9Sstevel@tonic-gate sbus_clear_intr(softsp, (uint64_t *)&t_afsr); 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "SBus%d Error: AFSR 0x%08x.%08x " 662*7c478bd9Sstevel@tonic-gate "AFAR 0x%08x.%08x Id %d\n", 663*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 664*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, id); 665*7c478bd9Sstevel@tonic-gate 666*7c478bd9Sstevel@tonic-gate debug_enter("sbus_err_intr"); 667*7c478bd9Sstevel@tonic-gate } else { 668*7c478bd9Sstevel@tonic-gate sbus_log_error(softsp, (uint64_t *)&t_afsr, 669*7c478bd9Sstevel@tonic-gate (uint64_t *)&t_afar, id, inst, cleared, otp); 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate if (!cleared) { 672*7c478bd9Sstevel@tonic-gate sbus_clear_intr(softsp, (uint64_t *)&t_afsr); 673*7c478bd9Sstevel@tonic-gate } 674*7c478bd9Sstevel@tonic-gate 675*7c478bd9Sstevel@tonic-gate return (DDI_INTR_CLAIMED); 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate static void 679*7c478bd9Sstevel@tonic-gate sbus_clear_intr(struct sbus_soft_state *softsp, uint64_t *pafsr) 680*7c478bd9Sstevel@tonic-gate { 681*7c478bd9Sstevel@tonic-gate volatile uint64_t *clear_reg; 682*7c478bd9Sstevel@tonic-gate 683*7c478bd9Sstevel@tonic-gate *softsp->sbus_err_reg = *pafsr; 684*7c478bd9Sstevel@tonic-gate clear_reg = (softsp->clr_intr_reg + SBUS_ERR_CLEAR); 685*7c478bd9Sstevel@tonic-gate *clear_reg = 0; 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate 688*7c478bd9Sstevel@tonic-gate static void 689*7c478bd9Sstevel@tonic-gate sbus_log_error(struct sbus_soft_state *softsp, uint64_t *pafsr, uint64_t *pafar, 690*7c478bd9Sstevel@tonic-gate ushort_t id, ushort_t inst, int cleared, on_trap_data_t *otp) 691*7c478bd9Sstevel@tonic-gate { 692*7c478bd9Sstevel@tonic-gate uint64_t t_afsr; 693*7c478bd9Sstevel@tonic-gate uint64_t t_afar; 694*7c478bd9Sstevel@tonic-gate int level = CE_WARN; 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate t_afsr = *pafsr; 697*7c478bd9Sstevel@tonic-gate t_afar = *pafar; 698*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_AFSR_P_LE) { 699*7c478bd9Sstevel@tonic-gate if (!cleared) 700*7c478bd9Sstevel@tonic-gate sbus_clear_intr(softsp, (uint64_t *)&t_afsr); 701*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "SBus%d Primary Error Late PIO: " 702*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x Id %d", 703*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 704*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, id); 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_AFSR_P_TO) { 707*7c478bd9Sstevel@tonic-gate if (otp != NULL && (otp->ot_prot & OT_DATA_ACCESS)) { 708*7c478bd9Sstevel@tonic-gate otp->ot_trap |= OT_DATA_ACCESS; 709*7c478bd9Sstevel@tonic-gate return; 710*7c478bd9Sstevel@tonic-gate } 711*7c478bd9Sstevel@tonic-gate if (sbus_check_bto(softsp)) { 712*7c478bd9Sstevel@tonic-gate if (!cleared) 713*7c478bd9Sstevel@tonic-gate sbus_clear_intr(softsp, (uint64_t *)&t_afsr); 714*7c478bd9Sstevel@tonic-gate level = CE_PANIC; 715*7c478bd9Sstevel@tonic-gate } 716*7c478bd9Sstevel@tonic-gate cmn_err(level, "SBus%d Primary Error Timeout: " 717*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x Id %d", 718*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 719*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, id); 720*7c478bd9Sstevel@tonic-gate } 721*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_AFSR_P_BERR) { 722*7c478bd9Sstevel@tonic-gate if (otp != NULL && (otp->ot_prot & OT_DATA_ACCESS)) { 723*7c478bd9Sstevel@tonic-gate otp->ot_trap |= OT_DATA_ACCESS; 724*7c478bd9Sstevel@tonic-gate return; 725*7c478bd9Sstevel@tonic-gate } 726*7c478bd9Sstevel@tonic-gate if (sbus_check_bto(softsp)) { 727*7c478bd9Sstevel@tonic-gate if (!cleared) 728*7c478bd9Sstevel@tonic-gate sbus_clear_intr(softsp, (uint64_t *)&t_afsr); 729*7c478bd9Sstevel@tonic-gate level = CE_PANIC; 730*7c478bd9Sstevel@tonic-gate } 731*7c478bd9Sstevel@tonic-gate cmn_err(level, "SBus%d Primary Error Bus Error: " 732*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x Id %d\n", 733*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 734*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, id); 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate 737*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_AFSR_S_LE) { 738*7c478bd9Sstevel@tonic-gate if (!cleared) 739*7c478bd9Sstevel@tonic-gate sbus_clear_intr(softsp, (uint64_t *)&t_afsr); 740*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "SBus%d Secondary Late PIO Error: " 741*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x Id %d", 742*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 743*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, id); 744*7c478bd9Sstevel@tonic-gate } 745*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_AFSR_S_TO) { 746*7c478bd9Sstevel@tonic-gate if (sbus_check_bto(softsp)) { 747*7c478bd9Sstevel@tonic-gate if (!cleared) 748*7c478bd9Sstevel@tonic-gate sbus_clear_intr(softsp, (uint64_t *)&t_afsr); 749*7c478bd9Sstevel@tonic-gate level = CE_PANIC; 750*7c478bd9Sstevel@tonic-gate } 751*7c478bd9Sstevel@tonic-gate cmn_err(level, "SBus%d Secondary Timeout Error: " 752*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x Id %d", 753*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 754*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, id); 755*7c478bd9Sstevel@tonic-gate } 756*7c478bd9Sstevel@tonic-gate if (t_afsr & SB_AFSR_S_BERR) { 757*7c478bd9Sstevel@tonic-gate if (sbus_check_bto(softsp)) { 758*7c478bd9Sstevel@tonic-gate if (!cleared) 759*7c478bd9Sstevel@tonic-gate sbus_clear_intr(softsp, (uint64_t *)&t_afsr); 760*7c478bd9Sstevel@tonic-gate level = CE_PANIC; 761*7c478bd9Sstevel@tonic-gate } 762*7c478bd9Sstevel@tonic-gate cmn_err(level, "SBus%d Secondary Bus Error: " 763*7c478bd9Sstevel@tonic-gate "AFSR 0x%08x.%08x AFAR 0x%08x.%08x Id %d", 764*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, 765*7c478bd9Sstevel@tonic-gate (uint32_t)(t_afar>>32), (uint32_t)t_afar, id); 766*7c478bd9Sstevel@tonic-gate } 767*7c478bd9Sstevel@tonic-gate } 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate 770*7c478bd9Sstevel@tonic-gate static int 771*7c478bd9Sstevel@tonic-gate sbus_check_bto(struct sbus_soft_state *softsp) 772*7c478bd9Sstevel@tonic-gate { 773*7c478bd9Sstevel@tonic-gate hrtime_t now = gethrtime(); /* high PIL safe */ 774*7c478bd9Sstevel@tonic-gate hrtime_t diff = now - softsp->bto_timestamp; 775*7c478bd9Sstevel@tonic-gate 776*7c478bd9Sstevel@tonic-gate if (diff > ((hrtime_t)bto_secs * NANOSEC) || diff < 0LL) { 777*7c478bd9Sstevel@tonic-gate /* 778*7c478bd9Sstevel@tonic-gate * Reset error counter as this bus error has occurred 779*7c478bd9Sstevel@tonic-gate * after more than bto_secs duration. 780*7c478bd9Sstevel@tonic-gate */ 781*7c478bd9Sstevel@tonic-gate softsp->bto_timestamp = now; 782*7c478bd9Sstevel@tonic-gate softsp->bto_ctr = 0; 783*7c478bd9Sstevel@tonic-gate } 784*7c478bd9Sstevel@tonic-gate if (softsp->bto_ctr++ >= bto_cnt) 785*7c478bd9Sstevel@tonic-gate return (1); 786*7c478bd9Sstevel@tonic-gate return (0); 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate static uint_t 790*7c478bd9Sstevel@tonic-gate sbus_ctrl_ecc_err(struct sbus_soft_state *softsp) 791*7c478bd9Sstevel@tonic-gate { 792*7c478bd9Sstevel@tonic-gate uint64_t t_sb_csr; 793*7c478bd9Sstevel@tonic-gate ushort_t id, inst; 794*7c478bd9Sstevel@tonic-gate 795*7c478bd9Sstevel@tonic-gate t_sb_csr = *softsp->sbus_ctrl_reg; 796*7c478bd9Sstevel@tonic-gate id = (ushort_t)softsp->upa_id; 797*7c478bd9Sstevel@tonic-gate inst = (ushort_t)ddi_get_instance(softsp->dip); 798*7c478bd9Sstevel@tonic-gate 799*7c478bd9Sstevel@tonic-gate if (debug_sysio_errs) { 800*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "sbus_ctrl_ecc_error: SBus%d Control Reg " 801*7c478bd9Sstevel@tonic-gate "0x%016llx Id %d\n", inst, (u_longlong_t)t_sb_csr, id); 802*7c478bd9Sstevel@tonic-gate } 803*7c478bd9Sstevel@tonic-gate 804*7c478bd9Sstevel@tonic-gate if (t_sb_csr & (SB_CSR_DPERR_S14|SB_CSR_DPERR_S13|SB_CSR_DPERR_S3| 805*7c478bd9Sstevel@tonic-gate SB_CSR_DPERR_S2|SB_CSR_DPERR_S1|SB_CSR_DPERR_S0|SB_CSR_PIO_PERRS)) { 806*7c478bd9Sstevel@tonic-gate struct async_flt aflt; 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate *softsp->sbus_ctrl_reg = t_sb_csr; /* clear error bits */ 809*7c478bd9Sstevel@tonic-gate 810*7c478bd9Sstevel@tonic-gate bzero(&aflt, sizeof (aflt)); 811*7c478bd9Sstevel@tonic-gate aflt.flt_id = gethrtime(); 812*7c478bd9Sstevel@tonic-gate aflt.flt_stat = t_sb_csr; 813*7c478bd9Sstevel@tonic-gate aflt.flt_func = sbus_log_csr_error; 814*7c478bd9Sstevel@tonic-gate aflt.flt_bus_id = id; 815*7c478bd9Sstevel@tonic-gate aflt.flt_inst = inst; 816*7c478bd9Sstevel@tonic-gate aflt.flt_status = ECC_IOBUS; 817*7c478bd9Sstevel@tonic-gate aflt.flt_class = BUS_FAULT; 818*7c478bd9Sstevel@tonic-gate aflt.flt_panic = 1; 819*7c478bd9Sstevel@tonic-gate 820*7c478bd9Sstevel@tonic-gate errorq_dispatch(ue_queue, &aflt, sizeof (aflt), aflt.flt_panic); 821*7c478bd9Sstevel@tonic-gate return (BF_FATAL); 822*7c478bd9Sstevel@tonic-gate } 823*7c478bd9Sstevel@tonic-gate 824*7c478bd9Sstevel@tonic-gate return (BF_NONE); 825*7c478bd9Sstevel@tonic-gate } 826*7c478bd9Sstevel@tonic-gate 827*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 828*7c478bd9Sstevel@tonic-gate static void 829*7c478bd9Sstevel@tonic-gate sbus_log_csr_error(struct async_flt *aflt, char *unum) 830*7c478bd9Sstevel@tonic-gate { 831*7c478bd9Sstevel@tonic-gate uint64_t t_sb_csr = aflt->flt_stat; 832*7c478bd9Sstevel@tonic-gate uint_t id = aflt->flt_bus_id; 833*7c478bd9Sstevel@tonic-gate uint_t inst = aflt->flt_inst; 834*7c478bd9Sstevel@tonic-gate 835*7c478bd9Sstevel@tonic-gate /* 836*7c478bd9Sstevel@tonic-gate * Print out SBus error information. 837*7c478bd9Sstevel@tonic-gate */ 838*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_DPERR_S14) { 839*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 840*7c478bd9Sstevel@tonic-gate "SBus%d Slot 14 DVMA Parity Error: AFSR 0x%08x.%08x Id %d", 841*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 842*7c478bd9Sstevel@tonic-gate } 843*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_DPERR_S13) { 844*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 845*7c478bd9Sstevel@tonic-gate "SBus%d Slot 13 DVMA Parity Error: AFSR 0x%08x.%08x Id %d", 846*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 847*7c478bd9Sstevel@tonic-gate } 848*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_DPERR_S3) { 849*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 850*7c478bd9Sstevel@tonic-gate "SBus%d Slot 3 DVMA Parity Error: AFSR 0x%08x.%08x Id %d", 851*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 852*7c478bd9Sstevel@tonic-gate } 853*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_DPERR_S2) { 854*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 855*7c478bd9Sstevel@tonic-gate "SBus%d Slot 2 DVMA Parity Error: AFSR 0x%08x.%08x Id %d", 856*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 857*7c478bd9Sstevel@tonic-gate } 858*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_DPERR_S1) { 859*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 860*7c478bd9Sstevel@tonic-gate "SBus%d Slot 1 DVMA Parity Error: AFSR 0x%08x.%08x Id %d", 861*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 862*7c478bd9Sstevel@tonic-gate } 863*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_DPERR_S0) { 864*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 865*7c478bd9Sstevel@tonic-gate "SBus%d Slot 0 DVMA Parity Error: AFSR 0x%08x.%08x Id %d", 866*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 867*7c478bd9Sstevel@tonic-gate } 868*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_PPERR_S15) { 869*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 870*7c478bd9Sstevel@tonic-gate "SBus%d Slot 15 PIO Parity Error: AFSR 0x%08x.%08x Id %d", 871*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 872*7c478bd9Sstevel@tonic-gate } 873*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_PPERR_S14) { 874*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 875*7c478bd9Sstevel@tonic-gate "SBus%d Slot 14 PIO Parity Error: AFSR 0x%08x.%08x Id %d", 876*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 877*7c478bd9Sstevel@tonic-gate } 878*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_PPERR_S13) { 879*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 880*7c478bd9Sstevel@tonic-gate "SBus%d Slot 13 PIO Parity Error: AFSR 0x%08x.%08x Id %d", 881*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 882*7c478bd9Sstevel@tonic-gate } 883*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_PPERR_S3) { 884*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 885*7c478bd9Sstevel@tonic-gate "SBus%d Slot 3 PIO Parity Error: AFSR 0x%08x.%08x Id %d", 886*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 887*7c478bd9Sstevel@tonic-gate } 888*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_PPERR_S2) { 889*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 890*7c478bd9Sstevel@tonic-gate "SBus%d Slot 2 PIO Parity Error: AFSR 0x%08x.%08x Id %d", 891*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 892*7c478bd9Sstevel@tonic-gate } 893*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_PPERR_S1) { 894*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 895*7c478bd9Sstevel@tonic-gate "SBus%d Slot 1 PIO Parity Error: AFSR 0x%08x.%08x Id %d", 896*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 897*7c478bd9Sstevel@tonic-gate } 898*7c478bd9Sstevel@tonic-gate if (t_sb_csr & SB_CSR_PPERR_S0) { 899*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 900*7c478bd9Sstevel@tonic-gate "SBus%d Slot 0 PIO Parity Error: AFSR 0x%08x.%08x Id %d", 901*7c478bd9Sstevel@tonic-gate inst, (uint32_t)(t_sb_csr>>32), (uint32_t)t_sb_csr, id); 902*7c478bd9Sstevel@tonic-gate } 903*7c478bd9Sstevel@tonic-gate } 904*7c478bd9Sstevel@tonic-gate 905*7c478bd9Sstevel@tonic-gate /* 906*7c478bd9Sstevel@tonic-gate * Sysio Thermal Warning interrupt handler 907*7c478bd9Sstevel@tonic-gate */ 908*7c478bd9Sstevel@tonic-gate static uint_t 909*7c478bd9Sstevel@tonic-gate sysio_thermal_warn_intr(struct sbus_soft_state *softsp) 910*7c478bd9Sstevel@tonic-gate { 911*7c478bd9Sstevel@tonic-gate volatile uint64_t *clear_reg; 912*7c478bd9Sstevel@tonic-gate volatile uint64_t tmp_mondo_vec; 913*7c478bd9Sstevel@tonic-gate volatile uint64_t *mondo_vec_reg; 914*7c478bd9Sstevel@tonic-gate const char thermal_warn_msg[] = 915*7c478bd9Sstevel@tonic-gate "Severe over-temperature condition detected!"; 916*7c478bd9Sstevel@tonic-gate 917*7c478bd9Sstevel@tonic-gate /* 918*7c478bd9Sstevel@tonic-gate * Take off the Thermal Warning interrupt and 919*7c478bd9Sstevel@tonic-gate * remove its interrupt handler. 920*7c478bd9Sstevel@tonic-gate */ 921*7c478bd9Sstevel@tonic-gate mondo_vec_reg = (softsp->intr_mapping_reg + THERMAL_MAPREG); 922*7c478bd9Sstevel@tonic-gate tmp_mondo_vec = *mondo_vec_reg; 923*7c478bd9Sstevel@tonic-gate tmp_mondo_vec &= ~INTERRUPT_VALID; 924*7c478bd9Sstevel@tonic-gate *mondo_vec_reg = tmp_mondo_vec; 925*7c478bd9Sstevel@tonic-gate 926*7c478bd9Sstevel@tonic-gate ddi_remove_intr(softsp->dip, 4, NULL); 927*7c478bd9Sstevel@tonic-gate 928*7c478bd9Sstevel@tonic-gate clear_reg = (softsp->clr_intr_reg + THERMAL_CLEAR); 929*7c478bd9Sstevel@tonic-gate *clear_reg = 0; 930*7c478bd9Sstevel@tonic-gate 931*7c478bd9Sstevel@tonic-gate if (oven_test) { 932*7c478bd9Sstevel@tonic-gate cmn_err(CE_NOTE, "OVEN TEST: %s", thermal_warn_msg); 933*7c478bd9Sstevel@tonic-gate return (DDI_INTR_CLAIMED); 934*7c478bd9Sstevel@tonic-gate } 935*7c478bd9Sstevel@tonic-gate 936*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "%s", thermal_warn_msg); 937*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "Powering down..."); 938*7c478bd9Sstevel@tonic-gate 939*7c478bd9Sstevel@tonic-gate do_shutdown(); 940*7c478bd9Sstevel@tonic-gate 941*7c478bd9Sstevel@tonic-gate /* 942*7c478bd9Sstevel@tonic-gate * just in case do_shutdown() fails 943*7c478bd9Sstevel@tonic-gate */ 944*7c478bd9Sstevel@tonic-gate (void) timeout((void(*)(void *))power_down, NULL, 945*7c478bd9Sstevel@tonic-gate thermal_powerdown_delay * hz); 946*7c478bd9Sstevel@tonic-gate 947*7c478bd9Sstevel@tonic-gate return (DDI_INTR_CLAIMED); 948*7c478bd9Sstevel@tonic-gate } 949