Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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);
}
Exemple #4
0
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);
}
Exemple #5
0
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);
}
Exemple #6
0
		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;