Browse Source

opal-prd package update

Signed-off-by: basebuilder_pel7ppc64bebuilder0 <basebuilder@powerel.org>
master
basebuilder_pel7ppc64bebuilder0 7 years ago
parent
commit
3647e986fc
  1. 478
      SOURCES/opal-prd-49999302251b3e3e2fdca2cbcdeb6aab9add7412.patch
  2. 321
      SOURCES/opal-prd-781b10633945df32fa2292ee8b196c74f8ef2c7c.patch
  3. 12
      SOURCES/opal-prd.service
  4. 138
      SPECS/opal-prd.spec

478
SOURCES/opal-prd-49999302251b3e3e2fdca2cbcdeb6aab9add7412.patch

@ -0,0 +1,478 @@
diff -up skiboot-5.9/core/hostservices.c.me skiboot-5.9/core/hostservices.c
--- skiboot-5.9/core/hostservices.c.me 2017-10-31 05:29:28.000000000 +0100
+++ skiboot-5.9/core/hostservices.c 2018-01-22 11:42:23.462547265 +0100
@@ -697,34 +697,49 @@ static int hservice_clr_special_wakeup(s
return 0;
}
-static int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
+int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
{
+ int (*set_wakeup)(struct cpu_thread *cpu);
+ int (*clear_wakeup)(struct cpu_thread *cpu);
struct cpu_thread *cpu;
int rc = OPAL_SUCCESS;
- /*
- * Mask out the top nibble of i_core since it may contain
- * 0x4 (which we use for XSCOM targeting)
- */
- i_core &= 0x0fffffff;
+ switch (proc_gen) {
+ case proc_gen_p8:
+ /*
+ * Mask out the top nibble of i_core since it may contain
+ * 0x4 (which we use for XSCOM targeting)
+ */
+ i_core &= 0x0fffffff;
+ i_core <<= 3;
+ set_wakeup = hservice_set_special_wakeup;
+ clear_wakeup = hservice_clr_special_wakeup;
+ break;
+ case proc_gen_p9:
+ i_core &= SPR_PIR_P9_MASK;
+ i_core <<= 2;
+ set_wakeup = dctl_set_special_wakeup;
+ clear_wakeup = dctl_clear_special_wakeup;
+ break;
+ default:
+ return OPAL_UNSUPPORTED;
+ }
/* What do we need to do ? */
switch(i_mode) {
case 0: /* Assert special wakeup */
- /* XXX Assume P8 */
- cpu = find_cpu_by_pir(i_core << 3);
+ cpu = find_cpu_by_pir(i_core);
if (!cpu)
return OPAL_PARAMETER;
prlog(PR_DEBUG, "HBRT: Special wakeup assert for core 0x%x,"
" count=%d\n", i_core, cpu->hbrt_spec_wakeup);
if (cpu->hbrt_spec_wakeup == 0)
- rc = hservice_set_special_wakeup(cpu);
+ rc = set_wakeup(cpu);
if (rc == 0)
cpu->hbrt_spec_wakeup++;
return rc;
case 1: /* Deassert special wakeup */
- /* XXX Assume P8 */
- cpu = find_cpu_by_pir(i_core << 3);
+ cpu = find_cpu_by_pir(i_core);
if (!cpu)
return OPAL_PARAMETER;
prlog(PR_DEBUG, "HBRT: Special wakeup release for core"
@@ -738,7 +753,7 @@ static int hservice_wakeup(uint32_t i_co
/* What to do with count on errors ? */
cpu->hbrt_spec_wakeup--;
if (cpu->hbrt_spec_wakeup == 0)
- rc = hservice_clr_special_wakeup(cpu);
+ rc = clear_wakeup(cpu);
return rc;
case 2: /* Clear all special wakeups */
prlog(PR_DEBUG, "HBRT: Special wakeup release for all cores\n");
@@ -746,7 +761,7 @@ static int hservice_wakeup(uint32_t i_co
if (cpu->hbrt_spec_wakeup) {
cpu->hbrt_spec_wakeup = 0;
/* What to do on errors ? */
- hservice_clr_special_wakeup(cpu);
+ clear_wakeup(cpu);
}
}
return OPAL_SUCCESS;
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 2017-10-31 05:29:28.000000000 +0100
+++ skiboot-5.9/external/opal-prd/opal-prd.c 2018-01-22 11:42:23.463547227 +0100
@@ -163,6 +163,9 @@ struct func_desc {
void *toc;
} hbrt_entry;
+static int nr_chips;
+static u64 chips[256];
+
static int read_prd_msg(struct opal_prd_ctx *ctx);
static struct prd_range *find_range(const char *name, uint32_t instance)
@@ -521,6 +524,24 @@ int hservice_i2c_write(uint64_t i_master
i_offset, i_length, i_data);
}
+int hservice_wakeup(u32 core, u32 mode)
+{
+ struct opal_prd_msg msg;
+
+ msg.hdr.type = OPAL_PRD_MSG_TYPE_CORE_SPECIAL_WAKEUP;
+ msg.hdr.size = htobe16(sizeof(msg));
+ msg.spl_wakeup.core = htobe32(core);
+ msg.spl_wakeup.mode = htobe32(mode);
+
+ if (write(ctx->fd, &msg, sizeof(msg)) != sizeof(msg)) {
+ pr_log(LOG_ERR, "FW: Failed to send CORE_SPECIAL_WAKEUP msg %x : %m\n",
+ core);
+ return -1;
+ }
+
+ return 0;
+}
+
static void ipmi_init(struct opal_prd_ctx *ctx)
{
insert_module("ipmi_devintf");
@@ -1170,6 +1191,52 @@ static void print_ranges(struct opal_prd
}
}
+static int chip_init(void)
+{
+ struct dirent *dirent;
+ char *path;
+ DIR *dir;
+ __be32 *chipid;
+ void *buf;
+ int rc, len, i;
+
+ dir = opendir(devicetree_base);
+ if (!dir) {
+ pr_log(LOG_ERR, "FW: Can't open %s", devicetree_base);
+ return -1;
+ }
+
+ for (;;) {
+ dirent = readdir(dir);
+ if (!dirent)
+ break;
+
+ if (strncmp("xscom", dirent->d_name, 5))
+ continue;
+
+ rc = asprintf(&path, "%s/%s/ibm,chip-id", devicetree_base,
+ dirent->d_name);
+ if (rc < 0) {
+ pr_log(LOG_ERR, "FW: Failed to create chip-id path");
+ return -1;
+ }
+
+ rc = open_and_read(path, &buf, &len);
+ if (rc) {
+ pr_log(LOG_ERR, "FW; Failed to read chipid");
+ return -1;
+ }
+ chipid = buf;
+ chips[nr_chips++] = be32toh(*chipid);
+ }
+
+ pr_log(LOG_DEBUG, "FW: Chip init");
+ for (i = 0; i < nr_chips; i++)
+ pr_log(LOG_DEBUG, "FW: Chip 0x%lx", chips[i]);
+
+ return 0;
+}
+
static int prd_init_ranges(struct opal_prd_ctx *ctx)
{
struct dirent *dirent;
@@ -1290,6 +1357,10 @@ static int prd_init(struct opal_prd_ctx
return -1;
}
+ rc = chip_init();
+ if (rc)
+ pr_log(LOG_ERR, "FW: Failed to initialize chip IDs");
+
return 0;
}
@@ -1433,6 +1504,41 @@ static int handle_msg_sbe_passthrough(st
return rc;
}
+static int handle_msg_fsp_occ_reset(struct opal_prd_msg *msg)
+{
+ struct opal_prd_msg omsg;
+ int rc = -1, i;
+
+ pr_debug("FW: FSP requested OCC reset");
+
+ if (!hservice_runtime->reset_pm_complex) {
+ pr_log_nocall("reset_pm_complex");
+ return rc;
+ }
+
+ for (i = 0; i < nr_chips; i++) {
+ pr_debug("PM: calling pm_complex_reset(0x%lx)", chips[i]);
+ rc = call_reset_pm_complex(chips[i]);
+ if (rc) {
+ pr_log(LOG_ERR, "PM: Failed pm_complex_reset(0x%lx) %m",
+ chips[i]);
+ break;
+ }
+ }
+
+ omsg.hdr.type = OPAL_PRD_MSG_TYPE_FSP_OCC_RESET_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_RESET_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;
@@ -1453,6 +1559,9 @@ static int handle_prd_msg(struct opal_pr
case OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH:
rc = handle_msg_sbe_passthrough(ctx, msg);
break;
+ case OPAL_PRD_MSG_TYPE_FSP_OCC_RESET:
+ rc = handle_msg_fsp_occ_reset(msg);
+ break;
default:
pr_log(LOG_WARNING, "Invalid incoming message type 0x%x",
msg->hdr.type);
@@ -1985,6 +2094,9 @@ static int run_prd_daemon(struct opal_pr
hinterface.pnor_write = NULL;
}
+ if (!is_fsp_system())
+ hinterface.wakeup = NULL;
+
ipmi_init(ctx);
pr_debug("HBRT: calling hservices_init");
diff -up skiboot-5.9/external/opal-prd/thunk.S.me skiboot-5.9/external/opal-prd/thunk.S
--- skiboot-5.9/external/opal-prd/thunk.S.me 2017-10-31 05:29:28.000000000 +0100
+++ skiboot-5.9/external/opal-prd/thunk.S 2018-01-22 11:42:23.463547227 +0100
@@ -183,7 +183,7 @@ hinterface:
DISABLED_THUNK(hservice_lid_load)
DISABLED_THUNK(hservice_lid_unload)
CALLBACK_THUNK(hservice_get_reserved_mem)
- DISABLED_THUNK(hservice_wakeup)
+ CALLBACK_THUNK(hservice_wakeup)
CALLBACK_THUNK(hservice_nanosleep)
DISABLED_THUNK(hservice_report_occ_failure)
CALLBACK_THUNK(hservice_clock_gettime)
diff -up skiboot-5.9/hw/occ.c.me skiboot-5.9/hw/occ.c
--- skiboot-5.9/hw/occ.c.me 2017-10-31 05:29:28.000000000 +0100
+++ skiboot-5.9/hw/occ.c 2018-01-22 11:42:23.463547227 +0100
@@ -1837,6 +1837,44 @@ out:
return rc;
}
+static u32 last_seq_id;
+
+int fsp_occ_reset_status(u64 chipid, s64 status)
+{
+ struct fsp_msg *stat;
+ int rc = OPAL_NO_MEM;
+ int status_word = 0;
+
+ prlog(PR_INFO, "HBRT: OCC stop() completed with %lld\n", status);
+
+ if (status) {
+ struct proc_chip *chip = get_chip(chipid);
+
+ if (!chip)
+ return OPAL_PARAMETER;
+
+ status_word = 0xfe00 | (chip->pcid & 0xff);
+ log_simple_error(&e_info(OPAL_RC_OCC_RESET),
+ "OCC: Error %lld in OCC reset of chip %lld\n",
+ status, chipid);
+ } else {
+ occ_msg_queue_occ_reset();
+ }
+
+ stat = fsp_mkmsg(FSP_CMD_RESET_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_RESET),
+ "OCC: Error %d queueing FSP OCC RESET STATUS message\n",
+ rc);
+ }
+ return rc;
+}
+
static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id)
{
struct fsp_msg *rsp, *stat;
@@ -1877,7 +1915,18 @@ static void occ_do_reset(u8 scope, u32 d
* FSP will request OCC to left in stopped state.
*/
- rc = host_services_occ_stop();
+ switch (proc_gen) {
+ case proc_gen_p8:
+ rc = host_services_occ_stop();
+ break;
+ case proc_gen_p9:
+ last_seq_id = seq_id;
+ chip = next_chip(NULL);
+ prd_fsp_occ_reset(chip->id);
+ return;
+ default:
+ return;
+ }
/* Handle fallback to preload */
if (rc == -ENOENT && chip->homer_base) {
diff -up skiboot-5.9/hw/prd.c.me skiboot-5.9/hw/prd.c
--- skiboot-5.9/hw/prd.c.me 2017-10-31 05:29:28.000000000 +0100
+++ skiboot-5.9/hw/prd.c 2018-01-22 11:42:23.464547189 +0100
@@ -29,6 +29,7 @@ enum events {
EVENT_OCC_ERROR = 1 << 1,
EVENT_OCC_RESET = 1 << 2,
EVENT_SBE_PASSTHROUGH = 1 << 3,
+ EVENT_FSP_OCC_RESET = 1 << 4,
};
static uint8_t events[MAX_CHIPS];
@@ -114,6 +115,10 @@ static void prd_msg_consumed(void *data)
proc = msg->sbe_passthrough.chip;
event = EVENT_SBE_PASSTHROUGH;
break;
+ case OPAL_PRD_MSG_TYPE_FSP_OCC_RESET:
+ proc = msg->occ_reset.chip;
+ event = EVENT_FSP_OCC_RESET;
+ break;
default:
prlog(PR_ERR, "PRD: invalid msg consumed, type: 0x%x\n",
msg->hdr.type);
@@ -188,6 +193,9 @@ static void send_next_pending_event(void
} else if (event & EVENT_SBE_PASSTHROUGH) {
prd_msg->hdr.type = OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH;
prd_msg->sbe_passthrough.chip = proc;
+ } else if (event & EVENT_FSP_OCC_RESET) {
+ prd_msg->hdr.type = OPAL_PRD_MSG_TYPE_FSP_OCC_RESET;
+ prd_msg->occ_reset.chip = proc;
}
/*
@@ -274,6 +282,11 @@ void prd_occ_reset(uint32_t proc)
prd_event(proc, EVENT_OCC_RESET);
}
+void prd_fsp_occ_reset(uint32_t proc)
+{
+ prd_event(proc, EVENT_FSP_OCC_RESET);
+}
+
void prd_sbe_passthrough(uint32_t proc)
{
prd_event(proc, EVENT_SBE_PASSTHROUGH);
@@ -418,6 +431,14 @@ static int64_t opal_prd_msg(struct opal_
case OPAL_PRD_MSG_TYPE_FIRMWARE_REQUEST:
rc = prd_msg_handle_firmware_req(msg);
break;
+ case OPAL_PRD_MSG_TYPE_FSP_OCC_RESET_STATUS:
+ rc = fsp_occ_reset_status(msg->fsp_occ_reset_status.chip,
+ msg->fsp_occ_reset_status.status);
+ break;
+ case OPAL_PRD_MSG_TYPE_CORE_SPECIAL_WAKEUP:
+ rc = hservice_wakeup(msg->spl_wakeup.core,
+ msg->spl_wakeup.mode);
+ 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:42:23.464547189 +0100
+++ skiboot-5.9/include/hostservices.h 2018-01-22 11:42:57.522259222 +0100
@@ -38,5 +38,7 @@ void host_services_occ_base_setup(void);
int find_master_and_slave_occ(uint64_t **master, uint64_t **slave,
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);
#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 2017-10-31 05:29:28.000000000 +0100
+++ skiboot-5.9/include/opal-api.h 2018-01-22 11:42:23.465547151 +0100
@@ -1054,6 +1054,9 @@ enum opal_prd_msg_type {
OPAL_PRD_MSG_TYPE_FIRMWARE_RESPONSE, /* HBRT <-- OPAL */
OPAL_PRD_MSG_TYPE_FIRMWARE_NOTIFY, /* HBRT <-- OPAL */
OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH, /* HBRT <-- OPAL */
+ 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 */
};
struct opal_prd_msg_header {
@@ -1101,6 +1104,14 @@ struct opal_prd_msg {
struct {
__be64 chip;
} sbe_passthrough;
+ struct {
+ __be64 chip;
+ __be64 status; /* 0 SUCCESS */
+ } fsp_occ_reset_status;
+ struct {
+ __be32 core;
+ __be32 mode;
+ } spl_wakeup;
};
};
diff -up skiboot-5.9/include/skiboot.h.me skiboot-5.9/include/skiboot.h
--- skiboot-5.9/include/skiboot.h.me 2017-10-31 05:29:28.000000000 +0100
+++ skiboot-5.9/include/skiboot.h 2018-01-22 11:42:23.465547151 +0100
@@ -293,6 +293,7 @@ extern void prd_occ_reset(uint32_t proc)
extern void prd_sbe_passthrough(uint32_t proc);
extern void prd_init(void);
extern void prd_register_reserved_memory(void);
+extern void prd_fsp_occ_reset(uint32_t proc);
/* Flatten device-tree */
extern void *create_dtb(const struct dt_node *root, bool exclusive);
diff -up skiboot-5.9/core/direct-controls.c.me skiboot-5.9/core/direct-controls.c
--- skiboot-5.9/core/direct-controls.c.me 2017-10-31 00:29:28.000000000 -0400
+++ skiboot-5.9/core/direct-controls.c 2018-01-22 07:12:07.642733620 -0500
@@ -220,7 +220,7 @@ static int p9_sreset_thread(struct cpu_t
return 0;
}
-static int dctl_set_special_wakeup(struct cpu_thread *t)
+int dctl_set_special_wakeup(struct cpu_thread *t)
{
struct cpu_thread *c = t->primary;
int rc = OPAL_SUCCESS;
@@ -238,7 +238,7 @@ static int dctl_set_special_wakeup(struc
return rc;
}
-static int dctl_clear_special_wakeup(struct cpu_thread *t)
+int dctl_clear_special_wakeup(struct cpu_thread *t)
{
struct cpu_thread *c = t->primary;
int rc = OPAL_SUCCESS;
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 07:14:59.985852136 -0500
+++ skiboot-5.9/hw/prd.c 2018-01-22 07:15:11.146054087 -0500
@@ -23,6 +23,7 @@
#include <fsp.h>
#include <mem_region.h>
#include <prd-fw-msg.h>
+#include <hostservices.h>
enum events {
EVENT_ATTN = 1 << 0,
diff -up skiboot-5.9/include/cpu.h.me skiboot-5.9/include/cpu.h
--- skiboot-5.9/include/cpu.h.me 2017-10-31 00:29:28.000000000 -0400
+++ skiboot-5.9/include/cpu.h 2018-01-22 07:12:07.642733620 -0500
@@ -284,4 +284,7 @@ extern void cpu_idle_delay(unsigned long
extern void cpu_set_radix_mode(void);
extern void cpu_fast_reboot_complete(void);
+int dctl_set_special_wakeup(struct cpu_thread *t);
+int dctl_clear_special_wakeup(struct cpu_thread *t);
+
#endif /* __CPU_H */

321
SOURCES/opal-prd-781b10633945df32fa2292ee8b196c74f8ef2c7c.patch

@ -0,0 +1,321 @@
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);

12
SOURCES/opal-prd.service

@ -0,0 +1,12 @@
[Unit]
Description=OPAL PRD daemon
ConditionArchitecture=ppc64-le
ConditionVirtualization=false
ConditionPathExists=/sys/firmware/devicetree/base/ibm,opal/diagnostics

[Service]
ExecStart=/usr/sbin/opal-prd --pnor /dev/mtd0
Restart=always

[Install]
WantedBy=multi-user.target

138
SPECS/opal-prd.spec

@ -0,0 +1,138 @@
Name: opal-prd
Version: 5.9
Release: 2%{?dist}
Summary: OPAL Processor Recovery Diagnostics Daemon

Group: System Environment/Daemons
License: ASL 2.0
URL: http://github.com/open-power/skiboot

# Presently opal-prd is supported on ppc64le architecture only.
ExclusiveArch: ppc64le

BuildRequires: systemd
BuildRequires: openssl-devel

Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd

Source0: https://github.com/open-power/skiboot/archive/v%{version}.tar.gz#/skiboot-%{version}.tar.gz
Source1: opal-prd.service

# upstream fix, Add support for runtime OCC load/start in ZZ
Patch0: opal-prd-49999302251b3e3e2fdca2cbcdeb6aab9add7412.patch
Patch1: opal-prd-781b10633945df32fa2292ee8b196c74f8ef2c7c.patch

%description
This package provides a daemon to load and run the OpenPower firmware's
Processor Recovery Diagnostics binary. This is responsible for run time
maintenance of OpenPower Systems hardware.


%package -n opal-utils
Summary: OPAL firmware utilities
Group: Applications/System

%description -n opal-utils
This package contains utility programs.

The 'gard' utility, can read, parse and clear hardware gard partitions
on OpenPower platforms. The 'getscom' and 'putscom' utilities provide
an interface to query or modify the registers of the different chipsets
of an OpenPower system. 'pflash' is a tool to access the flash modules
on such systems and update the OpenPower firmware.

%package -n opal-firmware
Summary: OPAL firmware
BuildArch: noarch

%description -n opal-firmware
OPAL firmware, aka skiboot, loads the bootloader and provides runtime
services to the OS (Linux) on IBM Power and OpenPower systems.

%prep

%setup -q -n skiboot-%{version}
%patch0 -p1
%patch1 -p1

%build
OPAL_PRD_VERSION=%{version} make V=1 CFLAGS="%{optflags}" -C external/opal-prd
GARD_VERSION=%{version} make V=1 CFLAGS="%{optflags}" -C external/gard
PFLASH_VERSION=%{version} make V=1 CFLAGS="%{optflags}" -C external/pflash
XSCOM_VERSION=%{version} make V=1 CFLAGS="%{optflags}" -C external/xscom-utils
SKIBOOT_VERSION=%{version} CROSS= make V=1 %{?_smp_mflags}

%install
make -C external/opal-prd install DESTDIR=%{buildroot} prefix=/usr
make -C external/gard install DESTDIR=%{buildroot} prefix=/usr
make -C external/pflash install DESTDIR=%{buildroot} prefix=/usr
make -C external/xscom-utils install DESTDIR=%{buildroot} prefix=/usr

mkdir -p %{buildroot}%{_unitdir}
install -m 644 -p %{SOURCE1} %{buildroot}%{_unitdir}/opal-prd.service

mkdir -p %{buildroot}%{_datadir}/qemu
install -m 644 -p skiboot.lid %{buildroot}%{_datadir}/qemu/skiboot.lid

%post
%systemd_post opal-prd.service

%preun
%systemd_preun opal-prd.service

%postun
%systemd_postun_with_restart opal-prd.service

%files
%doc README.md
%license LICENCE
%{_sbindir}/opal-prd
%{_unitdir}/opal-prd.service
%{_mandir}/man8/*

%files -n opal-utils
%doc README.md
%license LICENCE
%{_sbindir}/opal-gard
%{_sbindir}/getscom
%{_sbindir}/putscom
%{_sbindir}/getsram
%{_sbindir}/pflash
%{_mandir}/man1/*

%files -n opal-firmware
%doc README.md
%license LICENCE
%{_datadir}/qemu/

%changelog
* Mon Jan 22 2018 Than Ngo <than@redhat.com> - 5.9-2
- Related: rhbz#1456536 - add support for runtime OCC load/start in ZZ

* Tue Oct 31 2017 Dan Horák <dhorak@redhat.com> - 5.9-1
- Resolves: rhbz#1456536 - opal-prd update to 5.9

* Wed Oct 25 2017 Than Ngo <than@redhat.com> - 5.8-1
- Resolves: rhbz#1456536 - opal-prd update to 5.8

* Thu Apr 20 2017 Rafael Fonseca <rdossant@redhat.com> - 5.5.0-1
- Resolves: rhbz#1368702 - [Pegas1.0 FEAT] opal-prd package update

* Tue Mar 14 2017 Rafael Fonseca <rdossant@redhat.com> - 5.4.3-2
- Resolves: rhbz#1430332 - Restart opal-prd daemon on any kind of failure

* Wed Jan 18 2017 Rafael Fonseca <rdossant@redhat.com> - 5.4.3-1
- Resolves: rhbz#1384952 - [7.4 FEAT] opal-prd package update for ppc64le

* Thu Sep 22 2016 Rafael Fonseca <rdossant@redhat.com> - 5.2.0-3
- Resolves: rhbz#1375449

* Thu Aug 25 2016 Rafael Fonseca <rdossant@redhat.com> - 5.2.0-2
- Resolves: rhbz#1367342
- Remove systemd socket.

* Fri May 20 2016 Rafael dos Santos <rdossant@redhat.com> - 5.2.0-1
- Importing package from Fedora.

Loading…
Cancel
Save