From patchwork Mon Aug 31 15:43:11 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neelesh Gupta X-Patchwork-Id: 512533 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B829F1401E7 for ; Tue, 1 Sep 2015 01:44:16 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 963D91A1E34 for ; Tue, 1 Sep 2015 01:44:16 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from e28smtp09.in.ibm.com (e28smtp09.in.ibm.com [122.248.162.9]) (using TLSv1 with cipher CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 05EC81A1E42 for ; Tue, 1 Sep 2015 01:43:32 +1000 (AEST) Received: from /spool/local by e28smtp09.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 31 Aug 2015 21:13:30 +0530 Received: from d28dlp01.in.ibm.com (9.184.220.126) by e28smtp09.in.ibm.com (192.168.1.139) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 31 Aug 2015 21:13:27 +0530 X-Helo: d28dlp01.in.ibm.com X-MailFrom: neelegup@linux.vnet.ibm.com X-RcptTo: skiboot@lists.ozlabs.org Received: from d28relay04.in.ibm.com (d28relay04.in.ibm.com [9.184.220.61]) by d28dlp01.in.ibm.com (Postfix) with ESMTP id 50AD7E005E for ; Mon, 31 Aug 2015 21:12:44 +0530 (IST) Received: from d28av01.in.ibm.com (d28av01.in.ibm.com [9.184.220.63]) by d28relay04.in.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t7VFhH8S35651696 for ; Mon, 31 Aug 2015 21:13:17 +0530 Received: from d28av01.in.ibm.com (localhost [127.0.0.1]) by d28av01.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t7VFhHDA001026 for ; Mon, 31 Aug 2015 21:13:17 +0530 Received: from localhost.localdomain ([9.124.88.102]) by d28av01.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t7VFhFSm000780; Mon, 31 Aug 2015 21:13:15 +0530 From: Neelesh Gupta To: skiboot@lists.ozlabs.org Date: Mon, 31 Aug 2015 21:13:11 +0530 Message-ID: <20150831154304.12511.98184.stgit@localhost.localdomain> In-Reply-To: <20150831154033.12511.11165.stgit@localhost.localdomain> References: <20150831154033.12511.11165.stgit@localhost.localdomain> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15083115-0033-0000-0000-0000078C5B81 Subject: [Skiboot] [PATCH v3 5/5] external/opal-prd: Add 'run' option to execute HBRT commands X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dcrowell@us.ibm.com, whs@us.ibm.com, cjcain@us.ibm.com Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Vaidyanathan Srinivasan opal-prd client to accept run command and pass it as-is to hbrt. Example: opal-prd -d run test hbrt -t 1 -c "good cmd" argv[0] = test argv[1] = hbrt argv[2] = -t argv[3] = 1 argv[4] = -c argv[5] = good cmd Above argc/argv passed to hbrt->run_command() and result out string sent to the console. Signed-off-by: Vaidyanathan Srinivasan Signed-off-by: Neelesh Gupta --- external/opal-prd/hostboot-interface.h | 11 +++ external/opal-prd/opal-prd.c | 122 ++++++++++++++++++++++++++++++++ external/opal-prd/thunk.S | 1 3 files changed, 134 insertions(+) diff --git a/external/opal-prd/hostboot-interface.h b/external/opal-prd/hostboot-interface.h index 6cad5d9..73e25da 100644 --- a/external/opal-prd/hostboot-interface.h +++ b/external/opal-prd/hostboot-interface.h @@ -456,6 +456,17 @@ struct runtime_interfaces { int (*mfg_htmgt_pass_thru)(uint16_t i_cmdLength, uint8_t *i_cmdData, uint16_t *o_rspLength, uint8_t *o_rspData); + /** + * @brief Execute an arbitrary command inside hostboot runtime + * @param[in] Number of arguments (standard C args) + * @param[in] Array of argument values (standard C args) + * @param[out] Response message (NULL terminated), memory allocated + * by hbrt, if o_outString is NULL then no response will + * be sent + * @return 0 on success, else error code + */ + int (*run_command)(int argc, const char **argv, char **o_outString); + /* Reserve some space for future growth. */ void (*reserved[32])(void); }; diff --git a/external/opal-prd/opal-prd.c b/external/opal-prd/opal-prd.c index bab8b75..bb9cd83 100644 --- a/external/opal-prd/opal-prd.c +++ b/external/opal-prd/opal-prd.c @@ -86,6 +86,7 @@ enum control_msg_type { CONTROL_MSG_TEMP_OCC_ERROR = 0x03, CONTROL_MSG_ATTR_OVERRIDE = 0x04, CONTROL_MSG_HTMGT_PASSTHRU = 0x05, + CONTROL_MSG_RUN_CMD = 0x30, }; struct control_msg { @@ -227,6 +228,7 @@ extern void call_process_occ_reset(uint64_t i_chipId); extern int call_mfg_htmgt_pass_thru(uint16_t i_cmdLength, uint8_t *i_cmdData, uint16_t *o_rspLength, uint8_t *o_rspData); extern int call_apply_attr_override(uint8_t *i_data, size_t size); +extern int call_run_command(int argc, const char **argv, char **o_outString); void hservice_puts(const char *str) { @@ -1115,6 +1117,57 @@ static void handle_prd_control_htmgt_passthru(struct control_msg *send_msg, } } +static void handle_prd_control_run_cmd(struct control_msg *send_msg, + struct control_msg *recv_msg) +{ + char *runcmd_output, *s; + const char **argv; + int i, argc; + size_t size; + + if (!hservice_runtime->run_command) { + pr_log_nocall("run_command"); + return; + } + + argc = recv_msg->argc; + pr_debug("CTRL: run_command, argc:%d\n", argc); + + argv = malloc(argc * sizeof(*argv)); + if (!argv) { + pr_log(LOG_ERR, "CTRL: argv buffer malloc failed: %m"); + return; + } + + s = (char *)recv_msg->data; + for (i = 0; i < argc; i++) { + argv[i] = (char *)htobe64((uint64_t)&s[size]); + size += (strlen(&s[size]) + 1); + } + + /* Call HBRT */ + send_msg->response = call_run_command(argc, argv, &runcmd_output); + runcmd_output = (char *)be64toh((uint64_t)runcmd_output); + free(argv); + + s = (char *)send_msg->data; + if (runcmd_output) { + size = strlen(runcmd_output); + if (size >= MAX_CONTROL_MSG_BUF) { + pr_log(LOG_WARNING, "CTRL: output message truncated"); + runcmd_output[MAX_CONTROL_MSG_BUF] = '\0'; + size = MAX_CONTROL_MSG_BUF; + } + + strcpy(s, runcmd_output); + send_msg->data_len = size + 1; + free(runcmd_output); + } else { + strcpy(s, "Null"); + send_msg->data_len = strlen("Null") + 1; + } +} + static void handle_prd_control(struct opal_prd_ctx *ctx, int fd) { struct control_msg msg, *recv_msg, *send_msg; @@ -1181,6 +1234,9 @@ static void handle_prd_control(struct opal_prd_ctx *ctx, int fd) case CONTROL_MSG_HTMGT_PASSTHRU: handle_prd_control_htmgt_passthru(send_msg, recv_msg); break; + case CONTROL_MSG_RUN_CMD: + handle_prd_control_run_cmd(send_msg, recv_msg); + break; default: pr_log(LOG_WARNING, "CTRL: Unknown control message action %d", recv_msg->type); @@ -1589,6 +1645,58 @@ static int send_htmgt_passthru(struct opal_prd_ctx *ctx, int argc, char *argv[]) return rc; } +static int send_run_command(struct opal_prd_ctx *ctx, int argc, char *argv[]) +{ + struct control_msg *send_msg, *recv_msg = NULL; + uint32_t size = 0; + int rc, i; + char *s; + + if (!ctx->expert_mode) { + pr_log(LOG_WARNING, "CTRL: need to be in expert mode"); + return -1; + } + + if (ctx->debug) { + pr_debug("CTRL: run command arguments:"); + for (i=0; i < argc; i++) + pr_debug("argv[%d] = %s", i, argv[i]); + } + + for (i = 0; i < argc; i++) + size += (strlen(argv[i]) + 1); + + send_msg = malloc(sizeof(*send_msg) + size); + if (!send_msg) { + pr_log(LOG_ERR, "CTRL: msg buffer malloc failed: %m"); + return -1; + } + + /* Setup message */ + send_msg->type = CONTROL_MSG_RUN_CMD; + send_msg->argc = argc; + send_msg->data_len = size; + s = (char *)send_msg->data; + for (i = 0; i < argc; i++) { + strcpy(s, argv[i]); + s = s + strlen(argv[i]) + 1; + } + + rc = send_prd_control(send_msg, &recv_msg); + free(send_msg); + if (recv_msg) { + if (!rc) + pr_log(LOG_INFO, "Received: %s", recv_msg->data); + + if (recv_msg->response || ctx->debug) + pr_debug("CTRL: run command returned status %d", + recv_msg->response); + free(recv_msg); + } + + return rc; +} + static void usage(const char *progname) { printf("Usage:\n"); @@ -1597,6 +1705,7 @@ static void usage(const char *progname) printf("\t%s occ \n", progname); printf("\t%s htmgt-passthru \n", progname); printf("\t%s override \n", progname); + printf("\t%s run [arg 0] [arg 1]..[arg n]\n", progname); printf("\n"); printf("Options:\n" "\t--debug verbose logging for debug information\n" @@ -1628,6 +1737,7 @@ enum action { ACTION_OCC_CONTROL, ACTION_ATTR_OVERRIDE, ACTION_HTMGT_PASSTHRU, + ACTION_RUN_COMMAND, }; static int parse_action(const char *str, enum action *action) @@ -1646,6 +1756,9 @@ static int parse_action(const char *str, enum action *action) } else if (!strcmp(str, "htmgt-passthru")) { *action = ACTION_HTMGT_PASSTHRU; rc = 0; + } else if (!strcmp(str, "run")) { + *action = ACTION_RUN_COMMAND; + return 0; } else { pr_log(LOG_ERR, "CTRL: unknown argument '%s'", str); rc = -1; @@ -1742,6 +1855,15 @@ int main(int argc, char *argv[]) rc = send_htmgt_passthru(ctx, argc - optind - 1, &argv[optind + 1]); break; + case ACTION_RUN_COMMAND: + if (optind + 1 >= argc) { + pr_log(LOG_ERR, "CTRL: run command requires " + "argument(s)"); + return EXIT_FAILURE; + } + + rc = send_run_command(ctx, argc - optind - 1, &argv[optind + 1]); + break; default: break; } diff --git a/external/opal-prd/thunk.S b/external/opal-prd/thunk.S index 0c86976..7549efc 100644 --- a/external/opal-prd/thunk.S +++ b/external/opal-prd/thunk.S @@ -92,6 +92,7 @@ call_##name: ;\ CALL_THUNK(enable_occ_actuation, 11) CALL_THUNK(apply_attr_override, 12) CALL_THUNK(mfg_htmgt_pass_thru, 13) + CALL_THUNK(run_command, 14) .globl call_hbrt_init call_hbrt_init: