void p8_sbe_init_timer(void) { struct dt_node *np; int64_t rc; uint32_t tick_us; np = dt_find_compatible_node(dt_root, NULL, "ibm,power8-sbe-timer"); if (!np) return; sbe_timer_chip = dt_get_chip_id(np); tick_us = dt_prop_get_u32(np, "tick-time-us"); sbe_timer_inc = usecs_to_tb(tick_us); sbe_timer_target = ~0ull; rc = xscom_read(sbe_timer_chip, 0xE0006, &sbe_last_gen); if (rc) { prerror("SLW: Error %lld reading tmr gen count\n", rc); return; } sbe_last_gen_stamp = mftb(); prlog(PR_INFO, "SLW: Timer facility on chip %d, resolution %dus\n", sbe_timer_chip, tick_us); sbe_has_timer = true; }
static const struct slot_table_entry *match_slot_phb_entry(struct phb *phb) { uint32_t chip_id = dt_get_chip_id(phb->dt_node); uint32_t phb_idx = dt_prop_get_u32_def(phb->dt_node, "ibm,phb-index", 0); const struct slot_table_entry *ent; if (!slot_top_table) return NULL; for (ent = slot_top_table; ent->etype != st_end; ent++) { if (ent->etype != st_phb) { prerror("SLOT: Bad DEV entry type in table !\n"); continue; } if (ent->location == ST_LOC_PHB(chip_id, phb_idx)) return ent; } return NULL; }
void nx_create_compress_node(struct dt_node *node) { u32 gcid, pb_base; int rc; gcid = dt_get_chip_id(node); pb_base = dt_get_address(node, 0, NULL); prlog(PR_INFO, "NX%d: 842 at 0x%x\n", gcid, pb_base); if (dt_node_is_compatible(node, "ibm,power9-nx")) { u64 cfg_mmio, cfg_txwc, cfg_uctrl, cfg_dma; printf("Found ibm,power9-nx\n"); cfg_mmio = pb_base + NX_P9_UMAC_VAS_MMIO_BAR; cfg_dma = pb_base + NX_P9_DMA_VAS_MMIO_BAR; cfg_txwc = pb_base + NX_P9_UMAC_TX_WINDOW_CONTEXT_BAR; cfg_uctrl = pb_base + NX_P9_UMAC_STATUS_CTRL; rc = nx_cfg_umac_vas_mmio(gcid, cfg_mmio); if (rc) return; rc = nx_cfg_dma_vas_mmio(gcid, cfg_dma); if (rc) return; rc = nx_cfg_umac_tx_wc(gcid, cfg_txwc); if (rc) return; rc = nx_cfg_umac_status_ctrl(gcid, cfg_uctrl); if (rc) return; p9_nx_enable_842(node, gcid, pb_base); p9_nx_enable_gzip(node, gcid, pb_base); } else nx_enable_842(node, gcid, pb_base); }
static void find_npu_checkstop_reason(int flat_chip_id, struct OpalHMIEvent *hmi_evt, uint64_t *out_flags) { struct phb *phb; struct npu *p = NULL; uint64_t npu_fir; uint64_t npu_fir_mask; uint64_t npu_fir_action0; uint64_t npu_fir_action1; uint64_t fatal_errors; /* Only check for NPU errors if the chip has a NPU */ if (PVR_TYPE(mfspr(SPR_PVR)) != PVR_TYPE_P8NVL) return find_npu2_checkstop_reason(flat_chip_id, hmi_evt, out_flags); /* Find the NPU on the chip associated with the HMI. */ for_each_phb(phb) { /* NOTE: if a chip ever has >1 NPU this will need adjusting */ if (dt_node_is_compatible(phb->dt_node, "ibm,power8-npu-pciex") && (dt_get_chip_id(phb->dt_node) == flat_chip_id)) { p = phb_to_npu(phb); break; } } /* If we didn't find a NPU on the chip, it's not our checkstop. */ if (p == NULL) return; /* Read all the registers necessary to find a checkstop condition. */ if (xscom_read(flat_chip_id, p->at_xscom + NX_FIR, &npu_fir) || xscom_read(flat_chip_id, p->at_xscom + NX_FIR_MASK, &npu_fir_mask) || xscom_read(flat_chip_id, p->at_xscom + NX_FIR_ACTION0, &npu_fir_action0) || xscom_read(flat_chip_id, p->at_xscom + NX_FIR_ACTION1, &npu_fir_action1)) { prerror("Couldn't read NPU registers with XSCOM\n"); return; } fatal_errors = npu_fir & ~npu_fir_mask & npu_fir_action0 & npu_fir_action1; /* If there's no errors, we don't need to do anything. */ if (!fatal_errors) return; prlog(PR_DEBUG, "NPU: FIR 0x%016llx mask 0x%016llx\n", npu_fir, npu_fir_mask); prlog(PR_DEBUG, "NPU: ACTION0 0x%016llx, ACTION1 0x%016llx\n", npu_fir_action0, npu_fir_action1); /* Set the NPU to fenced since it can't recover. */ npu_set_fence_state(p, true); /* Set up the HMI event */ hmi_evt->severity = OpalHMI_SEV_WARNING; hmi_evt->type = OpalHMI_ERROR_MALFUNC_ALERT; hmi_evt->u.xstop_error.xstop_type = CHECKSTOP_TYPE_NPU; hmi_evt->u.xstop_error.u.chip_id = flat_chip_id; /* The HMI is "recoverable" because it shouldn't crash the system */ queue_hmi_event(hmi_evt, 1, out_flags); }
static void find_npu2_checkstop_reason(int flat_chip_id, struct OpalHMIEvent *hmi_evt, uint64_t *out_flags) { struct phb *phb; int i; bool npu2_hmi_verbose = false, found = false; uint64_t npu2_fir; uint64_t npu2_fir_mask; uint64_t npu2_fir_action0; uint64_t npu2_fir_action1; uint64_t npu2_fir_addr; uint64_t npu2_fir_mask_addr; uint64_t npu2_fir_action0_addr; uint64_t npu2_fir_action1_addr; uint64_t fatal_errors; int total_errors = 0; const char *loc; /* Find the NPU on the chip associated with the HMI. */ for_each_phb(phb) { /* NOTE: if a chip ever has >1 NPU this will need adjusting */ if (phb_is_npu2(phb->dt_node) && (dt_get_chip_id(phb->dt_node) == flat_chip_id)) { found = true; break; } } /* If we didn't find a NPU on the chip, it's not our checkstop. */ if (!found) return; npu2_fir_addr = NPU2_FIR_REGISTER_0; npu2_fir_mask_addr = NPU2_FIR_REGISTER_0 + NPU2_FIR_MASK_OFFSET; npu2_fir_action0_addr = NPU2_FIR_REGISTER_0 + NPU2_FIR_ACTION0_OFFSET; npu2_fir_action1_addr = NPU2_FIR_REGISTER_0 + NPU2_FIR_ACTION1_OFFSET; for (i = 0; i < NPU2_TOTAL_FIR_REGISTERS; i++) { /* Read all the registers necessary to find a checkstop condition. */ if (xscom_read(flat_chip_id, npu2_fir_addr, &npu2_fir) || xscom_read(flat_chip_id, npu2_fir_mask_addr, &npu2_fir_mask) || xscom_read(flat_chip_id, npu2_fir_action0_addr, &npu2_fir_action0) || xscom_read(flat_chip_id, npu2_fir_action1_addr, &npu2_fir_action1)) { prerror("HMI: Couldn't read NPU FIR register%d with XSCOM\n", i); continue; } fatal_errors = npu2_fir & ~npu2_fir_mask & npu2_fir_action0 & npu2_fir_action1; if (fatal_errors) { loc = chip_loc_code(flat_chip_id); if (!loc) loc = "Not Available"; prlog(PR_ERR, "NPU: [Loc: %s] P:%d FIR#%d FIR 0x%016llx mask 0x%016llx\n", loc, flat_chip_id, i, npu2_fir, npu2_fir_mask); prlog(PR_ERR, "NPU: [Loc: %s] P:%d ACTION0 0x%016llx, ACTION1 0x%016llx\n", loc, flat_chip_id, npu2_fir_action0, npu2_fir_action1); total_errors++; } /* Can't do a fence yet, we are just logging fir information for now */ npu2_fir_addr += NPU2_FIR_OFFSET; npu2_fir_mask_addr += NPU2_FIR_OFFSET; npu2_fir_action0_addr += NPU2_FIR_OFFSET; npu2_fir_action1_addr += NPU2_FIR_OFFSET; } if (!total_errors) return; npu2_hmi_verbose = nvram_query_eq_safe("npu2-hmi-verbose", "true"); /* Force this for now until we sort out something better */ npu2_hmi_verbose = true; if (npu2_hmi_verbose) { npu2_dump_scoms(flat_chip_id); prlog(PR_ERR, " _________________________ \n"); prlog(PR_ERR, "< It's Debug time! >\n"); prlog(PR_ERR, " ------------------------- \n"); prlog(PR_ERR, " \\ ,__, \n"); prlog(PR_ERR, " \\ (oo)____ \n"); prlog(PR_ERR, " (__) )\\ \n"); prlog(PR_ERR, " ||--|| * \n"); } /* Set up the HMI event */ hmi_evt->severity = OpalHMI_SEV_WARNING; hmi_evt->type = OpalHMI_ERROR_MALFUNC_ALERT; hmi_evt->u.xstop_error.xstop_type = CHECKSTOP_TYPE_NPU; hmi_evt->u.xstop_error.u.chip_id = flat_chip_id; /* Marking the event as recoverable so that we don't crash */ queue_hmi_event(hmi_evt, 1, out_flags); }
fsp_pcie_inv_alloc_count = new_count; /* Initialize the header for a new inventory */ if (need_init) { fsp_pcie_inv->version = 1; fsp_pcie_inv->num_entries = 0; fsp_pcie_inv->entry_size = sizeof(struct fsp_pcie_entry); fsp_pcie_inv->entry_offset = offsetof(struct fsp_pcie_inventory, entries); } } /* Add entry */ entry = &fsp_pcie_inv->entries[fsp_pcie_inv->num_entries++]; chip = get_chip(dt_get_chip_id(phb->dt_node)); if (!chip) { prerror("PLAT: Failed to get chip for PHB !\n"); return; } entry->hw_proc_id = chip->pcid; entry->slot_idx = pd->parent->slot_info->slot_index; entry->reserved = 0; pci_cfg_read16(phb, pd->bdfn, PCI_CFG_VENDOR_ID, &entry->vendor_id); pci_cfg_read16(phb, pd->bdfn, PCI_CFG_DEVICE_ID, &entry->device_id); if (pd->is_bridge) { int64_t ssvc = pci_find_cap(phb, pd->bdfn, PCI_CFG_CAP_ID_SUBSYS_VID); if (ssvc < 0) { entry->subsys_vendor_id = 0xffff; entry->subsys_device_id = 0xffff;