You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
321 lines
9.5 KiB
321 lines
9.5 KiB
diff -up skiboot-5.9/external/opal-prd/opal-prd.c.me skiboot-5.9/external/opal-prd/opal-prd.c |
|
--- skiboot-5.9/external/opal-prd/opal-prd.c.me 2018-01-22 11:44:50.353992246 +0100 |
|
+++ skiboot-5.9/external/opal-prd/opal-prd.c 2018-01-22 11:44:50.362991906 +0100 |
|
@@ -303,6 +303,8 @@ extern int call_sbe_message_passing(uint |
|
extern uint64_t call_get_ipoll_events(void); |
|
extern int call_firmware_notify(uint64_t len, void *data); |
|
extern int call_reset_pm_complex(uint64_t chip); |
|
+extern int call_load_pm_complex(u64 chip, u64 homer, u64 occ_common, u32 mode); |
|
+extern int call_start_pm_complex(u64 chip); |
|
|
|
void hservice_puts(const char *str) |
|
{ |
|
@@ -1418,6 +1420,61 @@ static int handle_msg_occ_error(struct o |
|
return 0; |
|
} |
|
|
|
+static int pm_complex_load_start(void) |
|
+{ |
|
+ struct prd_range *range; |
|
+ u64 homer, occ_common; |
|
+ int rc = -1, i; |
|
+ |
|
+ if (!hservice_runtime->load_pm_complex) { |
|
+ pr_log_nocall("load_pm_complex"); |
|
+ return rc; |
|
+ } |
|
+ |
|
+ if (!hservice_runtime->start_pm_complex) { |
|
+ pr_log_nocall("start_pm_complex"); |
|
+ return rc; |
|
+ } |
|
+ |
|
+ range = find_range("ibm,occ-common-area", 0); |
|
+ if (!range) { |
|
+ pr_log(LOG_ERR, "PM: ibm,occ-common-area not found"); |
|
+ return rc; |
|
+ } |
|
+ occ_common = range->physaddr; |
|
+ |
|
+ for (i = 0; i < nr_chips; i++) { |
|
+ range = find_range("ibm,homer-image", chips[i]); |
|
+ if (!range) { |
|
+ pr_log(LOG_ERR, "PM: ibm,homer-image not found 0x%lx", |
|
+ chips[i]); |
|
+ return -1; |
|
+ } |
|
+ homer = range->physaddr; |
|
+ |
|
+ pr_debug("PM: calling load_pm_complex(0x%lx, 0x%lx, 0x%lx, LOAD)", |
|
+ chips[i], homer, occ_common); |
|
+ rc = call_load_pm_complex(chips[i], homer, occ_common, 0); |
|
+ if (rc) { |
|
+ pr_log(LOG_ERR, "PM: Failed load_pm_complex(0x%lx) %m", |
|
+ chips[i]); |
|
+ return rc; |
|
+ } |
|
+ } |
|
+ |
|
+ for (i = 0; i < nr_chips; i++) { |
|
+ pr_debug("PM: calling start_pm_complex(0x%lx)", chips[i]); |
|
+ rc = call_start_pm_complex(chips[i]); |
|
+ if (rc) { |
|
+ pr_log(LOG_ERR, "PM: Failed start_pm_complex(0x%lx): %m", |
|
+ chips[i]); |
|
+ return rc; |
|
+ } |
|
+ } |
|
+ |
|
+ return rc; |
|
+} |
|
+ |
|
static int pm_complex_reset(uint64_t chip) |
|
{ |
|
int rc; |
|
@@ -1427,13 +1484,24 @@ static int pm_complex_reset(uint64_t chi |
|
* BMC system -> process_occ_reset |
|
*/ |
|
if (is_fsp_system()) { |
|
+ int i; |
|
+ |
|
if (!hservice_runtime->reset_pm_complex) { |
|
pr_log_nocall("reset_pm_complex"); |
|
return -1; |
|
} |
|
|
|
- pr_debug("PM: calling pm_complex_reset(%ld)", chip); |
|
- rc = call_reset_pm_complex(chip); |
|
+ for (i = 0; i < nr_chips; i++) { |
|
+ pr_debug("PM: calling pm_complex_reset(%ld)", chips[i]); |
|
+ rc = call_reset_pm_complex(chip); |
|
+ if (rc) { |
|
+ pr_log(LOG_ERR, "PM: Failed pm_complex_reset(%ld): %m", |
|
+ chips[i]); |
|
+ return rc; |
|
+ } |
|
+ } |
|
+ |
|
+ rc = pm_complex_load_start(); |
|
} else { |
|
if (!hservice_runtime->process_occ_reset) { |
|
pr_log_nocall("process_occ_reset"); |
|
@@ -1539,6 +1607,27 @@ static int handle_msg_fsp_occ_reset(stru |
|
return rc; |
|
} |
|
|
|
+static int handle_msg_fsp_occ_load_start(struct opal_prd_msg *msg) |
|
+{ |
|
+ struct opal_prd_msg omsg; |
|
+ int rc; |
|
+ |
|
+ pr_debug("FW: FSP requested OCC load/start"); |
|
+ rc = pm_complex_load_start(); |
|
+ |
|
+ omsg.hdr.type = OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START_STATUS; |
|
+ omsg.hdr.size = htobe16(sizeof(omsg)); |
|
+ omsg.fsp_occ_reset_status.chip = msg->occ_reset.chip; |
|
+ omsg.fsp_occ_reset_status.status = htobe64(rc); |
|
+ |
|
+ if (write(ctx->fd, &omsg, sizeof(omsg)) != sizeof(omsg)) { |
|
+ pr_log(LOG_ERR, "FW: Failed to send FSP_OCC_LOAD_START_STATUS msg: %m"); |
|
+ return -1; |
|
+ } |
|
+ |
|
+ return rc; |
|
+} |
|
+ |
|
static int handle_prd_msg(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg) |
|
{ |
|
int rc = -1; |
|
@@ -1562,6 +1651,9 @@ static int handle_prd_msg(struct opal_pr |
|
case OPAL_PRD_MSG_TYPE_FSP_OCC_RESET: |
|
rc = handle_msg_fsp_occ_reset(msg); |
|
break; |
|
+ case OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START: |
|
+ rc = handle_msg_fsp_occ_load_start(msg); |
|
+ break; |
|
default: |
|
pr_log(LOG_WARNING, "Invalid incoming message type 0x%x", |
|
msg->hdr.type); |
|
diff -up skiboot-5.9/hw/occ.c.me skiboot-5.9/hw/occ.c |
|
--- skiboot-5.9/hw/occ.c.me 2018-01-22 11:44:50.355992171 +0100 |
|
+++ skiboot-5.9/hw/occ.c 2018-01-22 11:44:50.362991906 +0100 |
|
@@ -1748,6 +1748,8 @@ void occ_poke_load_queue(void) |
|
} |
|
} |
|
|
|
+static u32 last_seq_id; |
|
+static bool in_ipl = true; |
|
static void occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id) |
|
{ |
|
struct fsp_msg *rsp; |
|
@@ -1780,15 +1782,25 @@ static void occ_do_load(u8 scope, u32 db |
|
return; |
|
|
|
if (proc_gen == proc_gen_p9) { |
|
- rc = -ENOMEM; |
|
- /* OCC is pre-loaded in P9, so send SUCCESS to FSP */ |
|
- rsp = fsp_mkmsg(FSP_CMD_LOAD_OCC_STAT, 2, 0, seq_id); |
|
- if (rsp) |
|
+ if (in_ipl) { |
|
+ /* OCC is pre-loaded in P9, so send SUCCESS to FSP */ |
|
+ rsp = fsp_mkmsg(FSP_CMD_LOAD_OCC_STAT, 2, 0, seq_id); |
|
+ if (!rsp) |
|
+ return; |
|
+ |
|
rc = fsp_queue_msg(rsp, fsp_freemsg); |
|
- if (rc) { |
|
- log_simple_error(&e_info(OPAL_RC_OCC_LOAD), |
|
- "OCC: Error %d queueing FSP OCC LOAD STATUS msg", rc); |
|
- fsp_freemsg(rsp); |
|
+ if (rc) { |
|
+ log_simple_error(&e_info(OPAL_RC_OCC_LOAD), |
|
+ "OCC: Error %d queueing OCC LOAD STATUS msg", |
|
+ rc); |
|
+ fsp_freemsg(rsp); |
|
+ } |
|
+ in_ipl = false; |
|
+ } else { |
|
+ struct proc_chip *chip = next_chip(NULL); |
|
+ |
|
+ last_seq_id = seq_id; |
|
+ prd_fsp_occ_load_start(chip->id); |
|
} |
|
return; |
|
} |
|
@@ -1837,8 +1849,6 @@ out: |
|
return rc; |
|
} |
|
|
|
-static u32 last_seq_id; |
|
- |
|
int fsp_occ_reset_status(u64 chipid, s64 status) |
|
{ |
|
struct fsp_msg *stat; |
|
@@ -1875,6 +1885,38 @@ int fsp_occ_reset_status(u64 chipid, s64 |
|
return rc; |
|
} |
|
|
|
+int fsp_occ_load_start_status(u64 chipid, s64 status) |
|
+{ |
|
+ struct fsp_msg *stat; |
|
+ int rc = OPAL_NO_MEM; |
|
+ int status_word = 0; |
|
+ |
|
+ if (status) { |
|
+ struct proc_chip *chip = get_chip(chipid); |
|
+ |
|
+ if (!chip) |
|
+ return OPAL_PARAMETER; |
|
+ |
|
+ status_word = 0xB500 | (chip->pcid & 0xff); |
|
+ log_simple_error(&e_info(OPAL_RC_OCC_LOAD), |
|
+ "OCC: Error %d in load/start OCC %lld\n", rc, |
|
+ chipid); |
|
+ } |
|
+ |
|
+ stat = fsp_mkmsg(FSP_CMD_LOAD_OCC_STAT, 2, status_word, last_seq_id); |
|
+ if (!stat) |
|
+ return rc; |
|
+ |
|
+ rc = fsp_queue_msg(stat, fsp_freemsg); |
|
+ if (rc) { |
|
+ fsp_freemsg(stat); |
|
+ log_simple_error(&e_info(OPAL_RC_OCC_LOAD), |
|
+ "OCC: Error %d queueing FSP OCC LOAD STATUS msg", rc); |
|
+ } |
|
+ |
|
+ return rc; |
|
+} |
|
+ |
|
static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id) |
|
{ |
|
struct fsp_msg *rsp, *stat; |
|
diff -up skiboot-5.9/hw/prd.c.me skiboot-5.9/hw/prd.c |
|
--- skiboot-5.9/hw/prd.c.me 2018-01-22 11:44:50.356992133 +0100 |
|
+++ skiboot-5.9/hw/prd.c 2018-01-22 11:44:50.363991868 +0100 |
|
@@ -30,6 +30,7 @@ enum events { |
|
EVENT_OCC_RESET = 1 << 2, |
|
EVENT_SBE_PASSTHROUGH = 1 << 3, |
|
EVENT_FSP_OCC_RESET = 1 << 4, |
|
+ EVENT_FSP_OCC_LOAD_START = 1 << 5, |
|
}; |
|
|
|
static uint8_t events[MAX_CHIPS]; |
|
@@ -119,6 +120,10 @@ static void prd_msg_consumed(void *data) |
|
proc = msg->occ_reset.chip; |
|
event = EVENT_FSP_OCC_RESET; |
|
break; |
|
+ case OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START: |
|
+ proc = msg->occ_reset.chip; |
|
+ event = EVENT_FSP_OCC_LOAD_START; |
|
+ break; |
|
default: |
|
prlog(PR_ERR, "PRD: invalid msg consumed, type: 0x%x\n", |
|
msg->hdr.type); |
|
@@ -196,6 +201,9 @@ static void send_next_pending_event(void |
|
} else if (event & EVENT_FSP_OCC_RESET) { |
|
prd_msg->hdr.type = OPAL_PRD_MSG_TYPE_FSP_OCC_RESET; |
|
prd_msg->occ_reset.chip = proc; |
|
+ } else if (event & EVENT_FSP_OCC_LOAD_START) { |
|
+ prd_msg->hdr.type = OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START; |
|
+ prd_msg->occ_reset.chip = proc; |
|
} |
|
|
|
/* |
|
@@ -292,6 +300,11 @@ void prd_sbe_passthrough(uint32_t proc) |
|
prd_event(proc, EVENT_SBE_PASSTHROUGH); |
|
} |
|
|
|
+void prd_fsp_occ_load_start(uint32_t proc) |
|
+{ |
|
+ prd_event(proc, EVENT_FSP_OCC_LOAD_START); |
|
+} |
|
+ |
|
/* incoming message handlers */ |
|
static int prd_msg_handle_attn_ack(struct opal_prd_msg *msg) |
|
{ |
|
@@ -439,6 +452,10 @@ static int64_t opal_prd_msg(struct opal_ |
|
rc = hservice_wakeup(msg->spl_wakeup.core, |
|
msg->spl_wakeup.mode); |
|
break; |
|
+ case OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START_STATUS: |
|
+ rc = fsp_occ_load_start_status(msg->fsp_occ_reset_status.chip, |
|
+ msg->fsp_occ_reset_status.status); |
|
+ break; |
|
default: |
|
rc = OPAL_UNSUPPORTED; |
|
} |
|
diff -up skiboot-5.9/include/hostservices.h.me skiboot-5.9/include/hostservices.h |
|
--- skiboot-5.9/include/hostservices.h.me 2018-01-22 11:44:50.363991868 +0100 |
|
+++ skiboot-5.9/include/hostservices.h 2018-01-22 11:45:21.221824912 +0100 |
|
@@ -40,5 +40,6 @@ int find_master_and_slave_occ(uint64_t * |
|
int *nr_masters, int *nr_slaves); |
|
int hservice_wakeup(uint32_t i_core, uint32_t i_mode); |
|
int fsp_occ_reset_status(u64 chipid, s64 status); |
|
+int fsp_occ_load_start_status(u64 chipid, s64 status); |
|
|
|
#endif /* __HOSTSERVICES_H */ |
|
diff -up skiboot-5.9/include/opal-api.h.me skiboot-5.9/include/opal-api.h |
|
--- skiboot-5.9/include/opal-api.h.me 2018-01-22 11:44:50.357992095 +0100 |
|
+++ skiboot-5.9/include/opal-api.h 2018-01-22 11:44:50.363991868 +0100 |
|
@@ -1057,6 +1057,8 @@ enum opal_prd_msg_type { |
|
OPAL_PRD_MSG_TYPE_FSP_OCC_RESET, /* HBRT <-- OPAL */ |
|
OPAL_PRD_MSG_TYPE_FSP_OCC_RESET_STATUS, /* HBRT --> OPAL */ |
|
OPAL_PRD_MSG_TYPE_CORE_SPECIAL_WAKEUP, /* HBRT --> OPAL */ |
|
+ OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START, /* HBRT <-- OPAL */ |
|
+ OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START_STATUS, /* HBRT --> OPAL */ |
|
}; |
|
|
|
struct opal_prd_msg_header { |
|
diff -up skiboot-5.9/include/skiboot.h.me skiboot-5.9/include/skiboot.h |
|
--- skiboot-5.9/include/skiboot.h.me 2018-01-22 11:44:50.358992057 +0100 |
|
+++ skiboot-5.9/include/skiboot.h 2018-01-22 11:44:50.364991831 +0100 |
|
@@ -294,6 +294,7 @@ extern void prd_sbe_passthrough(uint32_t |
|
extern void prd_init(void); |
|
extern void prd_register_reserved_memory(void); |
|
extern void prd_fsp_occ_reset(uint32_t proc); |
|
+extern void prd_fsp_occ_load_start(u32 proc); |
|
|
|
/* Flatten device-tree */ |
|
extern void *create_dtb(const struct dt_node *root, bool exclusive);
|
|
|