void op_display(enum op_severity sev, enum op_module mod, uint16_t code) { uint32_t w0 = sev << 16 | mod; uint32_t w1; bool clean_lock; if (!fsp_present()) return; w1 = tohex((code >> 12) & 0xf) << 24; w1 |= tohex((code >> 8) & 0xf) << 16; w1 |= tohex((code >> 4) & 0xf) << 8; w1 |= tohex((code ) & 0xf); /* * We use lock_recursive to detect recursion. We avoid sending * the message if that happens as this could be a case of a * locking error in the FSP driver for example */ clean_lock = lock_recursive(&op_lock); if (!clean_lock) return; /* We don't use mkmsg, we use a preallocated msg to avoid * going down the malloc path etc... since this can be called * in case of fatal errors */ fsp_fillmsg(&op_msg, FSP_CMD_DISP_SRC_DIRECT, 3, 1, w0, w1); fsp_sync_msg(&op_msg, false); unlock(&op_lock); }
int64_t ibm_fsp_cec_power_down(uint64_t request) { /* Request is: * * 0 = normal * 1 = immediate * (we do not allow 2 for "pci cfg reset" just yet) */ if (request !=0 && request != 1) return OPAL_PARAMETER; if (!fsp_present()) return OPAL_UNSUPPORTED; /* Flash new firmware */ if (fsp_flash_term_hook) fsp_flash_term_hook(); printf("FSP: Sending shutdown command to FSP...\n"); if (fsp_sync_msg(fsp_mkmsg(FSP_CMD_POWERDOWN_NORM, 1, request), true)) return OPAL_BUSY_EVENT; fsp_reset_links(); return OPAL_SUCCESS; }
void op_panel_clear_src(void) { if (!fsp_present()) return; lock(&op_lock); fsp_fillmsg(&op_msg, FSP_CMD_CLEAR_SRC, 0); fsp_sync_msg(&op_msg, false); unlock(&op_lock); }
void op_panel_disable_src_echo(void) { if (!fsp_present()) return; lock(&op_lock); fsp_fillmsg(&op_msg, FSP_CMD_DIS_SRC_ECHO, 0); fsp_sync_msg(&op_msg, false); unlock(&op_lock); }
static void fsp_op_display_fatal(uint32_t w0, uint32_t w1) { static struct fsp_msg op_msg_resp; static struct fsp_msg op_msg = { .resp = &op_msg_resp, }; fsp_fillmsg(&op_msg, FSP_CMD_DISP_SRC_DIRECT, 3, 1, w0, w1); fsp_sync_msg(&op_msg, false); }
void op_panel_clear_src(void) { struct fsp_msg op_msg_resp; struct fsp_msg op_msg = { .resp = &op_msg_resp, }; if (!fsp_present()) return; fsp_fillmsg(&op_msg, FSP_CMD_CLEAR_SRC, 0); fsp_sync_msg(&op_msg, false); }
void op_panel_disable_src_echo(void) { struct fsp_msg op_msg_resp; struct fsp_msg op_msg = { .resp = &op_msg_resp, }; if (!fsp_present()) return; fsp_fillmsg(&op_msg, FSP_CMD_DIS_SRC_ECHO, 0); fsp_sync_msg(&op_msg, false); }
int64_t ibm_fsp_cec_reboot(void) { uint32_t cmd = FSP_CMD_REBOOT; if (!fsp_present()) return OPAL_UNSUPPORTED; /* Flash new firmware */ if (fsp_flash_term_hook && fsp_flash_term_hook() == OPAL_SUCCESS) cmd = FSP_CMD_DEEP_REBOOT; printf("FSP: Sending 0x%02x reboot command to FSP...\n", cmd); /* If that failed, talk to the FSP */ if (fsp_sync_msg(fsp_mkmsg(cmd, 0), true)) return OPAL_BUSY_EVENT; return OPAL_SUCCESS; }
static void firenze_send_pci_inventory(void) { uint64_t base, abase, end, aend, offset; int64_t rc; if (!fsp_pcie_inv) return; prlog(PR_DEBUG, "PLAT: Sending PCI inventory to FSP, table has" " %d entries\n", fsp_pcie_inv->num_entries); { unsigned int i; prlog(PR_DEBUG, "HWP SLT VDID DVID SVID SDID\n"); prlog(PR_DEBUG, "---------------------------\n"); for (i = 0; i < fsp_pcie_inv->num_entries; i++) { struct fsp_pcie_entry *e = &fsp_pcie_inv->entries[i]; prlog(PR_DEBUG, "%03d %03d %04x %04x %04x %04x\n", e->hw_proc_id, e->slot_idx, e->vendor_id, e->device_id, e->subsys_vendor_id, e->subsys_device_id); } } /* * Get the location of the table in a form we can send * to the FSP */ base = (uint64_t)fsp_pcie_inv; end = base + sizeof(struct fsp_pcie_inventory) + fsp_pcie_inv->num_entries * fsp_pcie_inv->entry_size; abase = base & ~0xffful; aend = (end + 0xffful) & ~0xffful; offset = PSI_DMA_PCIE_INVENTORY + (base & 0xfff); /* We can only accomodate so many entries in the PSI map */ if ((aend - abase) > PSI_DMA_PCIE_INVENTORY_SIZE) { prerror("PLAT: PCIe inventory too large (%lld bytes)\n", aend - abase); goto bail; } /* Map this in the TCEs */ fsp_tce_map(PSI_DMA_PCIE_INVENTORY, (void *)abase, aend - abase); /* Send FSP message */ rc = fsp_sync_msg(fsp_mkmsg(FSP_CMD_PCI_POWER_CONF, 3, hi32(offset), lo32(offset), end - base), true); if (rc) prerror("PLAT: FSP error %lld sending inventory\n", rc); /* Unmap */ fsp_tce_unmap(PSI_DMA_PCIE_INVENTORY, aend - abase); bail: /* * We free the inventory. We'll have to redo that on hotplug * when we support it but that isn't the case yet */ free(fsp_pcie_inv); fsp_pcie_inv = NULL; }