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_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); }
void op_display(enum op_severity sev, enum op_module mod, uint16_t code) { struct fsp_msg *op_msg; uint32_t w0; uint32_t w1; if (!fsp_present()) return; w0 = sev << 16 | mod; w1 = tohex((code >> 12) & 0xf) << 24; w1 |= tohex((code >> 8) & 0xf) << 16; w1 |= tohex((code >> 4) & 0xf) << 8; w1 |= tohex((code ) & 0xf); if (sev == OP_FATAL) { fsp_op_display_fatal(w0, w1); } else { op_msg = fsp_allocmsg(true); if (!op_msg) { prerror("Failed to allocate FSP message for PANEL\n"); return; } fsp_fillmsg(op_msg, FSP_CMD_DISP_SRC_DIRECT, 3, 1, w0, w1); if(fsp_queue_msg(op_msg, fsp_freemsg)) prerror("Failed to queue FSP message for OP PANEL\n"); } }
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); }
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); }
void prd_init(void) { struct proc_chip *chip; /* mask everything */ lock(&ipoll_lock); for_each_chip(chip) { __ipoll_update_mask(chip->id, true, PRD_IPOLL_MASK); } unlock(&ipoll_lock); if (fsp_present()) { /* todo: FSP implementation */ queue_prd_msg = queue_prd_msg_nop; } else { queue_prd_msg = queue_prd_msg_hbrt; opal_register(OPAL_PRD_MSG, opal_prd_msg, 1); } }
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; }
void ibm_fsp_init(void) { /* Early initializations of the FSP interface */ fsp_init(); map_debug_areas(); fsp_sysparam_init(); /* Get ready to receive E0 class messages. We need to respond * to some of these for the init sequence to make forward progress */ fsp_console_preinit(); /* Get ready to receive OCC related messages */ occ_fsp_init(); /* Get ready to receive Memory [Un]corretable Error messages. */ fsp_memory_err_init(); /* Initialize elog access */ fsp_elog_read_init(); fsp_elog_write_init(); /* Initiate dump service */ fsp_dump_init(); /* Start FSP/HV state controller & perform OPL */ fsp_opl(); /* Preload hostservices lids */ hservices_lid_preload(); /* Initialize SP attention area */ fsp_attn_init(); /* Initialize monitoring of TOD topology change event notification */ fsp_chiptod_init(); /* Send MDST table notification to FSP */ op_display(OP_LOG, OP_MOD_INIT, 0x0000); fsp_mdst_table_init(); /* Initialize the panel */ op_display(OP_LOG, OP_MOD_INIT, 0x0001); fsp_oppanel_init(); /* Start the surveillance process */ op_display(OP_LOG, OP_MOD_INIT, 0x0002); fsp_init_surveillance(); /* IPMI */ fsp_ipmi_init(); ipmi_opal_init(); /* Initialize sensor access */ op_display(OP_LOG, OP_MOD_INIT, 0x0003); fsp_init_sensor(); /* LED */ op_display(OP_LOG, OP_MOD_INIT, 0x0004); fsp_led_init(); /* Monitor for DIAG events */ op_display(OP_LOG, OP_MOD_INIT, 0x0005); fsp_init_diag(); /* Finish initializing the console */ op_display(OP_LOG, OP_MOD_INIT, 0x0006); fsp_console_init(); /* Read our initial RTC value */ op_display(OP_LOG, OP_MOD_INIT, 0x0008); fsp_rtc_init(); /* Initialize code update access */ op_display(OP_LOG, OP_MOD_INIT, 0x0009); fsp_code_update_init(); /* EPOW */ op_display(OP_LOG, OP_MOD_INIT, 0x000A); fsp_epow_init(); /* EPOW */ op_display(OP_LOG, OP_MOD_INIT, 0x000B); fsp_dpo_init(); /* Setup console */ if (fsp_present()) fsp_console_add_nodes(); if (proc_gen >= proc_gen_p9) prd_init(); }