int pc_madr_add(int lboard, int rboard, int proc, uint_t madr) { register int i; uint_t madr_rd, madr_off; uint64_t pc_madr_addr; pc_madr_addr = STARFIRE_PC_MADR_ADDR(lboard, rboard, proc); /* * First write with Presence bit disabled * and then with it enabled. */ madr_off = madr & ~STARFIRE_MC_MEM_PRESENT_MASK; stphysio(pc_madr_addr, madr_off); for (i = 0; i < 20; i++) { madr_rd = ldphysio(pc_madr_addr); if (madr_off == madr_rd) break; } if (madr_off != madr_rd) { cmn_err(CE_WARN, "pc_madr_add: (1) failed to update " "PC MADR (%d, %d, %d, 0x%x)\n", lboard, rboard, proc, madr); return (-1); } if (madr == madr_off) { /* * Caller wanted to write value out there * with presence bit turned off, which is * what we just completed. So, we're finished. */ return (0); } /* * Now write with Presence bit enabled. */ stphysio(pc_madr_addr, madr); for (i = 0; i < 20; i++) { madr_rd = ldphysio(pc_madr_addr); if (madr == madr_rd) break; } if (madr != madr_rd) { cmn_err(CE_WARN, "pc_madr_add: (2) failed to update " "PC MADR (%d, %d, %d, 0x%x)\n", lboard, rboard, proc, madr); return (-1); } return (0); }
int mc_get_dimm_size(pnode_t nodeid) { uint64_t psi_addr; uint_t dimmtype; int i, rlen; struct sf_memunit_regspec reg; rlen = prom_getproplen(nodeid, "reg"); if (rlen != sizeof (struct sf_memunit_regspec)) return (-1); if (prom_getprop(nodeid, "reg", (caddr_t)®) < 0) return (-1); psi_addr = ((uint64_t)reg.regspec_addr_hi) << 32; psi_addr |= (uint64_t)reg.regspec_addr_lo; psi_addr = STARFIRE_MC_DIMMTYPE_ADDR(psi_addr); if (psi_addr == (uint64_t)-1) return (-1); dimmtype = ldphysio(psi_addr); dimmtype &= STARFIRE_MC_DIMMSIZE_MASK; for (i = 0; dimmsize_table[i].mc_type != 0; i++) if (dimmsize_table[i].mc_type == dimmtype) break; return (dimmsize_table[i].mc_module_size); }
int mc_read_asr(pnode_t nodeid, uint_t *mcregp) { uint64_t psi_addr; *mcregp = 0; psi_addr = mc_get_asr_addr(nodeid); if (psi_addr == (uint64_t)-1) return (-1); *mcregp = ldphysio(psi_addr); return (0); }
static uint_t pcmu_pbm_error_intr(caddr_t a) { pcmu_t *pcmu_p = (pcmu_t *)a; pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p; ddi_fm_error_t derr; int err = DDI_FM_OK; on_trap_data_t *otp = pcbm_p->pcbm_ontrap_data; bzero(&derr, sizeof (ddi_fm_error_t)); derr.fme_version = DDI_FME_VERSION; mutex_enter(&pcmu_p->pcmu_err_mutex); if ((otp != NULL) && (otp->ot_prot & OT_DATA_ACCESS)) { /* * ddi_poke protection, check nexus and children for * expected errors. */ otp->ot_trap |= OT_DATA_ACCESS; membar_sync(); derr.fme_flag = DDI_FM_ERR_POKE; err = pcmu_pbm_err_handler(pcmu_p->pcmu_dip, &derr, (void *)pcmu_p, PCI_INTR_CALL); } else if (pcmu_check_error(pcmu_p) != 0) { /* * unprotected error, check for all errors. */ if (pcmu_errtrig_pa) { (void) ldphysio(pcmu_errtrig_pa); } derr.fme_flag = DDI_FM_ERR_UNEXPECTED; err = pcmu_pbm_err_handler(pcmu_p->pcmu_dip, &derr, (void *)pcmu_p, PCI_INTR_CALL); } if (err == DDI_FM_FATAL) { if (pcmu_panic_on_fatal_errors) { mutex_exit(&pcmu_p->pcmu_err_mutex); cmn_err(CE_PANIC, "%s-%d: Fatal PCI bus error(s)\n", ddi_driver_name(pcmu_p->pcmu_dip), ddi_get_instance(pcmu_p->pcmu_dip)); } } mutex_exit(&pcmu_p->pcmu_err_mutex); pcmu_ib_nintr_clear(pcmu_p->pcmu_ib_p, pcmu_p->pcmu_inos[CBNINTR_PBM]); return (DDI_INTR_CLAIMED); }
int mc_write_asr(pnode_t nodeid, uint_t mcreg) { uint_t mcreg_rd; uint64_t psi_addr; psi_addr = mc_get_asr_addr(nodeid); if (psi_addr == (uint64_t)-1) return (-1); stphysio(psi_addr, mcreg); mcreg_rd = ldphysio(psi_addr); ASSERT(mcreg_rd == mcreg); return ((mcreg_rd != mcreg) ? -1 : 0); }
uint64_t mc_get_alignment_mask(pnode_t nodeid) { uint64_t psi_addr, seg_sz; uint_t mcreg, seg_sz_mask; int i, rlen; struct sf_memunit_regspec reg; rlen = prom_getproplen(nodeid, "reg"); if (rlen != sizeof (struct sf_memunit_regspec)) return (-1); if (prom_getprop(nodeid, "reg", (caddr_t)®) < 0) return (-1); psi_addr = ((uint64_t)reg.regspec_addr_hi) << 32; psi_addr |= (uint64_t)reg.regspec_addr_lo; psi_addr = STARFIRE_MC_ASR_ADDR(psi_addr); if (psi_addr == (uint64_t)-1) return (-1); mcreg = ldphysio(psi_addr); seg_sz_mask = (mcreg & STARFIRE_MC_MASK_MASK) >> 8; for (i = 0; mc_seg_table[i].seg_size != 0; i++) if (mc_seg_table[i].seg_mask == seg_sz_mask) break; if (mc_seg_table[i].seg_size == 0) seg_sz = mc_get_mem_alignment(); else seg_sz = mc_seg_table[i].seg_size; #ifdef DEBUG printf("nodeid %x, mc asr addr %lx, val %x, seg_sz_mask %x, " "seg_sz %lx\n", nodeid, psi_addr, mcreg, seg_sz_mask, seg_sz); #endif /* DEBUG */ return (seg_sz - 1); }