From patchwork Wed May 4 06:55:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhishek Singh Tomar X-Patchwork-Id: 1626095 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=gKAJkhcW; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=2404:9400:2:0:216:3eff:fee1:b9f1; helo=lists.ozlabs.org; envelope-from=skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2404:9400:2:0:216:3eff:fee1:b9f1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KtSM82HK5z9sG4 for ; Wed, 4 May 2022 16:57:40 +1000 (AEST) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4KtSM80sbKz3bcK for ; Wed, 4 May 2022 16:57:40 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=gKAJkhcW; dkim-atps=neutral X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com; envelope-from=abhishek@linux.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=gKAJkhcW; dkim-atps=neutral Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4KtSLt11k1z2xgY for ; Wed, 4 May 2022 16:57:25 +1000 (AEST) Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 2446Sfxi028116 for ; Wed, 4 May 2022 06:57:24 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=0Bmfnc7OIp0h8vstWu7dPJhF/PGL6hw37aZj/Ui3GLI=; b=gKAJkhcWUuqIAL2FuZ1SoXDreIye7izujuZRL0i+cYvhoF/z8/wOmUYFiUZzY1CA+3ZQ eJAab5H+tqrlrwUNb7i9Kt8CNW6V1vvoSFXaVz7+jWvxsIsfXfey09mHJaE/oYZPJcCO eBsN0+mZ2cs9WYdYls8hZJqwtRp+X1fGgEpRV8w7bGhIMH96Kpz5NtXpS2W7mypaYcxe 7YYNztbBO/Hw0i+eOGJoO+J4pChLvtq9pigNUurAtzxV48TXgZwft/E1Z38FM9lJjKok uE1pazmRVPhoMkv3GXE0bCGuU1HgHu+2zmbBe+tkZinVOjyF4oE+6GziN1E5p81TxX3/ QA== Received: from ppma04ams.nl.ibm.com (63.31.33a9.ip4.static.sl-reverse.com [169.51.49.99]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3fum8mrday-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 04 May 2022 06:57:23 +0000 Received: from pps.filterd (ppma04ams.nl.ibm.com [127.0.0.1]) by ppma04ams.nl.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 2446qPUI029780 for ; Wed, 4 May 2022 06:57:21 GMT Received: from b06cxnps4076.portsmouth.uk.ibm.com (d06relay13.portsmouth.uk.ibm.com [9.149.109.198]) by ppma04ams.nl.ibm.com with ESMTP id 3frvr8w6jm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 04 May 2022 06:57:21 +0000 Received: from d06av21.portsmouth.uk.ibm.com (d06av21.portsmouth.uk.ibm.com [9.149.105.232]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 2446vIF735062098 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 4 May 2022 06:57:18 GMT Received: from d06av21.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5480D52051; Wed, 4 May 2022 06:57:18 +0000 (GMT) Received: from li-22421c4c-355e-11b2-a85c-fdc6c782cba9.in.ibm.com (unknown [9.109.222.255]) by d06av21.portsmouth.uk.ibm.com (Postfix) with ESMTP id 761F25204E; Wed, 4 May 2022 06:57:17 +0000 (GMT) From: Abhishek Singh Tomar To: skiboot@lists.ozlabs.org Date: Wed, 4 May 2022 12:25:54 +0530 Message-Id: <20220504065555.20551-3-abhishek@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220504065555.20551-1-abhishek@linux.ibm.com> References: <20220504065555.20551-1-abhishek@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: Xhn_NPhdrBErHXrP_8zYstR2Umrxv3f7 X-Proofpoint-GUID: Xhn_NPhdrBErHXrP_8zYstR2Umrxv3f7 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.858,Hydra:6.0.486,FMLib:17.11.64.514 definitions=2022-05-04_01,2022-05-02_03,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 clxscore=1015 lowpriorityscore=0 malwarescore=0 bulkscore=0 mlxlogscore=999 mlxscore=0 priorityscore=1501 spamscore=0 adultscore=0 impostorscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2202240000 definitions=main-2205040040 Subject: [Skiboot] [PATCH 3/4] core/pldm/test : pldm platform test X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Abhishek Singh Tomar Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" The self test for PLDM platform message implementation Signed-off-by: Abhishek Singh Tomar --- core/pldm/test/Makefile.check | 1 + core/pldm/test/common/test_pldm-common.c | 15 +- core/pldm/test/test_pldm-platform.c | 353 +++++++++++++++++++++++ 3 files changed, 363 insertions(+), 6 deletions(-) create mode 100644 core/pldm/test/test_pldm-platform.c diff --git a/core/pldm/test/Makefile.check b/core/pldm/test/Makefile.check index ce43dea0..c184702f 100644 --- a/core/pldm/test/Makefile.check +++ b/core/pldm/test/Makefile.check @@ -1,6 +1,7 @@ # -*-Makefile-*- PLDM_TEST := core/pldm/test/test_pldm-fileio \ core/pldm/test/test_pldm-bios \ + core/pldm/test/test_pldm-platform \ LCOV_EXCLUDE += $(PLDM_TEST:%=%.c) diff --git a/core/pldm/test/common/test_pldm-common.c b/core/pldm/test/common/test_pldm-common.c index 4fb97ecd..8c424f63 100644 --- a/core/pldm/test/common/test_pldm-common.c +++ b/core/pldm/test/common/test_pldm-common.c @@ -132,12 +132,15 @@ int ast_mctp_message_tx(uint8_t eid, uint8_t *msg, int len) &response_msg, &response_len); if (ret != PLDM_SUCCESS) return ret; - vmsg = malloc(response_len+1); - // TYPE: PLDM = 0x01 (000_0001b) as per MCTP - DSP0240 - vmsg[0] = 0x01; - memcpy(vmsg + 1, response_msg, response_len); - - pldm_rx_message(BMC_EID, 0, 0, NULL, vmsg, response_len+1); + // If response length > 0 then response back + if (response_len > 0) { + vmsg = malloc(response_len+1); + + // TYPE: PLDM = 0x01 (000_0001b) as per MCTP - DSP0240 + vmsg[0] = 0x01; + memcpy(vmsg + 1, response_msg, response_len); + pldm_rx_message(BMC_EID, 0, 0, NULL, vmsg, response_len+1); + } } return PLDM_SUCCESS; diff --git a/core/pldm/test/test_pldm-platform.c b/core/pldm/test/test_pldm-platform.c new file mode 100644 index 00000000..c9e90ab2 --- /dev/null +++ b/core/pldm/test/test_pldm-platform.c @@ -0,0 +1,353 @@ +#include "common/test_pldm-common.c" + + +#define EFFECTER1_RECORD_HANDLE 120 +#define EFFECTER1_POSSIBLE_STATES PLDM_SW_TERM_GRACEFUL_RESTART_REQUESTED +#define EFFECTER2_RECORD_HANDLE 160 +#define EFFECTER2_POSSIBLE_STATES PLDM_STATE_SET_SYSTEM_POWER_STATE + + +/* + * These stucturs duplicate BMC functionality for Pldm self test + * It include PDR 1st entry to be send on behalf of BMC + */ +struct pldm_state_effecter_pdr effecter_test_1 = { + .hdr = { + .record_handle = EFFECTER1_RECORD_HANDLE + }, + .terminus_handle = 1, + .effecter_id = 38, + .entity_type = PLDM_ENTITY_SYS_FIRMWARE, + .entity_instance = 1, + .container_id = 1, + .effecter_semantic_id = 0, + .effecter_init = 0, + .has_description_pdr = 0, + .composite_effecter_count = 1 +}; +struct state_effecter_possible_states possible_states_effecter_1_test = { + .state_set_id = PLDM_STATE_SET_SW_TERMINATION_STATUS, + .possible_states_size = 1, + .states = { + {.byte = PLDM_SW_TERM_GRACEFUL_RESTART_REQUESTED} + } + +}; + + +/* + * These stucturs duplicate BMC functionality for Pldm self test + * It include PDR 2nd entry to be send on behalf of BMC + */ +struct pldm_state_effecter_pdr effecter_test_2 = { + .hdr = { + .record_handle = EFFECTER2_RECORD_HANDLE + }, + .terminus_handle = 1, + .effecter_id = 38, + .entity_type = PLDM_ENTITY_SYSTEM_CHASSIS, + .entity_instance = 1, + .container_id = 1, + .effecter_semantic_id = 0, + .effecter_init = 0, + .has_description_pdr = 0, + .composite_effecter_count = 1 +}; +struct state_effecter_possible_states possible_states_effecter_2_test = { + .state_set_id = PLDM_STATE_SET_SYSTEM_POWER_STATE, + .possible_states_size = 1, + .states = { + {.byte = PLDM_STATE_SET_SYS_POWER_STATE_OFF_SOFT_GRACEFUL} + } +}; + + +int pldm_test_reply_request(void *request_msg, size_t request_len, + void **response_msg, size_t *response_len); +int pldm_test_reply_request_platform(void *request_msg, size_t request_len, + void **response_msg, size_t *response_len); +uint32_t test_pdr_entry_generate(uint8_t **pdr, uint32_t record_hndl); + + +/* + * This function tries to duplicate BMC functionality for Pldm self test + * It will handle pldm response message + * For now we don't have any response + */ +int pldm_test_verify_response(void *response_msg, size_t response_len) +{ + if (response_len > 0 || response_msg != NULL) + return OPAL_PARAMETER; + return OPAL_PARAMETER; + +} + +/* + * This function tries to duplicate BMC functionality for Pldm self test + * This Genrate pdr entry for self test + */ +uint32_t test_pdr_entry_generate(uint8_t **pdr, + uint32_t record_hndl) +{ + int size; + size_t possible_states_size = 0; + struct pldm_state_effecter_pdr *effecter = NULL; + size_t actual_size; + struct pldm_state_effecter_pdr *effecter_test; + struct state_effecter_possible_states *possible_states_effecter_test; + + + // calculate sizeof whole struct + size = sizeof(struct pldm_state_effecter_pdr) + + sizeof(struct state_effecter_possible_states) - 1; + + if (record_hndl == 0) { + effecter_test = &effecter_test_1; + possible_states_effecter_test = &possible_states_effecter_1_test; + } else if (record_hndl == effecter_test_1.hdr.record_handle) { + effecter_test = &effecter_test_1; + possible_states_effecter_test = &possible_states_effecter_1_test; + } else if (record_hndl == effecter_test_2.hdr.record_handle) { + effecter_test = &effecter_test_2; + possible_states_effecter_test = &possible_states_effecter_2_test; + } else + return OPAL_PARAMETER; + + + *pdr = malloc(size); + memset(*pdr, 0, size); + effecter = (struct pldm_state_effecter_pdr *)(*pdr); + if (effecter == NULL) { + perror("malloc"); + exit(EXIT_FAILURE); + } + effecter->terminus_handle = effecter_test->terminus_handle; + effecter->effecter_id = effecter_test->effecter_id; + effecter->entity_type = effecter_test->entity_type; + effecter->entity_instance = effecter_test->entity_instance; + effecter->container_id = effecter_test->container_id; + effecter->effecter_semantic_id = effecter_test->effecter_semantic_id; + effecter->effecter_init = effecter_test->effecter_init; + effecter->has_description_pdr = effecter_test->has_description_pdr; + effecter->composite_effecter_count = effecter_test->composite_effecter_count; + + // consider only 1 possible state + possible_states_size = sizeof(struct state_effecter_possible_states) + + possible_states_effecter_test->possible_states_size - 1; + encode_state_effecter_pdr(effecter, size, + possible_states_effecter_test, + possible_states_size, &actual_size); + + return actual_size; + +} + +/* + * This function tries to duplicate BMC functionality for Pldm self test + * it tries to handle PLDM_REQUEST for PLDM_PLATFORM and reply with appropriate + * PLDM_RESPONSE message + * As pldm platfom test it will have only pldm request of type = PLDM_BIOS + */ +int pldm_test_reply_request(void *request_msg, size_t request_len, + void **response_msg, size_t *response_len) +{ + + switch (((struct pldm_msg *)request_msg)->hdr.type) { + case PLDM_PLATFORM: + return pldm_test_reply_request_platform(request_msg, request_len, + response_msg, response_len); + + default: + printf("PLDM_TEST: Not equal to PLDM_PLATFORM\n"); + return OPAL_PARAMETER; + } + + +} + + + +/* + * This function tries to duplicate BMC functionality for Pldm self test + * it tries to handle PLDM_REQUEST for PLDM_PLATFORM and reply with appropriate + * PLDM_RESPONSE message + */ +int pldm_test_reply_request_platform(void *request_msg, size_t request_len, + void **response_msg, size_t *response_len) +{ + //int size = 0; + uint8_t *pdr = NULL; + int ret = 0; + int payload_len = 0; + uint32_t transfer_handle; + uint8_t transfer_opflag; + uint16_t request_cnt; + uint16_t record_chg_num; + uint32_t record_hndl; + uint16_t effecter_id; + uint8_t comp_effecter_count; + set_effecter_state_field field; + uint8_t format_version, tid, event_class; + size_t event_data_offset; + +// check pldm command received and reply with appropriate pldm response message + switch (((struct pldm_msg *)request_msg)->hdr.command) { + case PLDM_GET_PDR: + + payload_len = request_len - sizeof(struct pldm_msg_hdr); + ret = decode_get_pdr_req(request_msg, payload_len, &record_hndl, &transfer_handle, + &transfer_opflag, &request_cnt, &record_chg_num); + if (ret != PLDM_SUCCESS) + return ret; + + // Generate pdr entry for self test + ret = test_pdr_entry_generate(&pdr, record_hndl); + if (ret < PLDM_SUCCESS) + return ret; + payload_len = (sizeof(struct pldm_get_pdr_resp) - 1) + + ret; + *response_len = sizeof(struct pldm_msg_hdr) + + payload_len; + *response_msg = malloc(*response_len); + + // if record_handle is equal to first record handle or 0 + // the encode next data transfer handle with 2nd record handle + if (record_hndl == EFFECTER1_RECORD_HANDLE || record_hndl == 0) { + ret = encode_get_pdr_resp(((struct pldm_msg *)request_msg)->hdr.instance_id, + PLDM_SUCCESS, EFFECTER2_RECORD_HANDLE, + PLDM_GET_NEXTPART, PLDM_START_AND_END, ret, pdr, 0, + *response_msg); + } + // if record_handle is equal to last record handle + // the encode next data transfer handle with 0 + else if (record_hndl == EFFECTER2_RECORD_HANDLE) { + ret = encode_get_pdr_resp(((struct pldm_msg *)request_msg)->hdr.instance_id, + PLDM_SUCCESS, 0, PLDM_GET_NEXTPART, PLDM_START_AND_END, + ret, pdr, 0, *response_msg); + } else + return OPAL_PARAMETER; + + free(pdr); + if (ret != PLDM_SUCCESS) + return ret; + break; + case PLDM_SET_STATE_EFFECTER_STATES: + + payload_len = request_len - sizeof(struct pldm_msg_hdr); + ret = decode_set_state_effecter_states_req(request_msg, payload_len, &effecter_id, + &comp_effecter_count, &field); + + // Test if request received from same effecter id passed + // and also check field struct same as expected + if ( + ( + effecter_id == effecter_test_1.effecter_id && + field.effecter_state == + possible_states_effecter_1_test.states->byte && + field.set_request == PLDM_REQUEST_SET && + field.effecter_state == PLDM_SW_TERM_GRACEFUL_RESTART_REQUESTED + + ) || + ( + effecter_id == effecter_test_2.effecter_id && + field.effecter_state == + possible_states_effecter_2_test.states->byte && + field.set_request == PLDM_REQUEST_SET && + field.effecter_state == + PLDM_STATE_SET_SYS_POWER_STATE_OFF_SOFT_GRACEFUL + ) + ) { + // BMC doesn't answer for these specific effecter states + // (PLDM_SW_TERM_GRACEFUL_RESTART and PLDM_STATE_SET_SYS_POWER_STATE_OFF) + // hence *response len = 0 + *response_len = 0; + return PLDM_SUCCESS; + } else + return OPAL_PARAMETER; + return PLDM_SUCCESS; + + case PLDM_PLATFORM_EVENT_MESSAGE: + payload_len = request_len - sizeof(struct pldm_msg_hdr); + ret = decode_platform_event_message_req(request_msg, payload_len, &format_version, + &tid, &event_class, &event_data_offset); + + // Test: if tid and event class same as that expected + if (tid != HOST_TID || event_class != PLDM_PDR_REPOSITORY_CHG_EVENT) + return OPAL_PARAMETER; + + *response_len = sizeof(struct pldm_msg_hdr) + + sizeof(struct pldm_platform_event_message_resp); + *response_msg = malloc(*response_len); + ret = encode_platform_event_message_resp( + ((struct pldm_msg *)request_msg)->hdr.instance_id, + PLDM_SUCCESS, 0, *response_msg); + return PLDM_SUCCESS; + + + + default: + return PLDM_ERROR_INVALID_DATA; + + } + + return PLDM_SUCCESS; + + + +} + + +int main(void) +{ + int ret; + +// Attempt to call pldm_platform_restart() +// before pldm_platform_init() return error +// OPAL_HARDWARE + ret = pldm_platform_restart(); + printf("pldm_platform_restart ends with %d\n", ret); + if (ret != OPAL_HARDWARE) { + perror("pldm_platform_restart"); + return ret; + } + + +// Attempt to call pldm_platform_power_off() +// before pldm_platform_init() return error +// OPAL_HARDWARE + ret = pldm_platform_power_off(); + printf("pldm_platform_power_off ends with %d\n", ret); + if (ret != OPAL_HARDWARE) { + perror("pldm_platform_restart"); + return ret; + } + +// Inittialize pldm platform + ret = pldm_platform_init(); + printf("pldm_platform_init ends with %d\n", ret); + if (ret != PLDM_SUCCESS) { + perror("pldm_platform_init"); + return ret; + } + + +// Attempt to call pldm_platform_restart() +// after pldm_platform_init() return PLDM_SUCCESS + ret = pldm_platform_restart(); + printf("pldm_platform_restart ends with %d\n", ret); + if (ret != PLDM_SUCCESS) { + perror("pldm_platform_restart"); + return ret; + } + +// Attempt to call pldm_platform_power_off() +// after pldm_platform_init() return PLDM_SUCCESS + ret = pldm_platform_power_off(); + printf("pldm_platform_power_off ends with %d\n", ret); + if (ret != PLDM_SUCCESS) { + perror("pldm_platform_restart"); + return ret; + } +} + +