aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorImre Kis <imre.kis@arm.com>2021-10-27 20:01:41 +0200
committerGyorgy Szing <Gyorgy.Szing@arm.com>2021-11-26 05:05:42 +0100
commit05f7936dae3734d2c5148b7c6941d91f118caa17 (patch)
tree14357d53ae2fe7f768446dbe56e2871a327f35ae
parente64a810ce073897661042e22ae7dce2a6e7b577f (diff)
downloadtrusted-services-05f7936dae3734d2c5148b7c6941d91f118caa17.tar.gz
Create SMM variable MM service
Create MM service for handling SMM variable service calls. This layer is called by the MM RPC layer and after parsing the SMM variable header it forwards the call to underlying the RPC interface. Signed-off-by: Imre Kis <imre.kis@arm.com> Change-Id: I38c7d8957cc1fe91c5d6972e4ab8dbb96f51a865
-rw-r--r--components/service/smm_variable/frontend/mm_communicate/component.cmake13
-rw-r--r--components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.c106
-rw-r--r--components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.h36
-rw-r--r--protocols/service/smm_variable/parameters.h15
4 files changed, 169 insertions, 1 deletions
diff --git a/components/service/smm_variable/frontend/mm_communicate/component.cmake b/components/service/smm_variable/frontend/mm_communicate/component.cmake
new file mode 100644
index 000000000..44c1042ee
--- /dev/null
+++ b/components/service/smm_variable/frontend/mm_communicate/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/smm_variable_mm_service.c"
+ )
diff --git a/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.c b/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.c
new file mode 100644
index 000000000..04970a831
--- /dev/null
+++ b/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include "protocols/common/mm/mm_smc.h"
+#include "protocols/service/smm_variable/smm_variable_proto.h"
+#include "smm_variable_mm_service.h"
+#include <assert.h>
+
+struct smm_variable_rpc_context {
+ struct rpc_interface *smm_variable_rpc_interface;
+};
+
+static int32_t convert_rpc_status(rpc_status_t rpc_status)
+{
+ switch (rpc_status) {
+ case TS_RPC_CALL_ACCEPTED:
+ return MM_RETURN_CODE_SUCCESS;
+
+ case TS_RPC_ERROR_EP_DOES_NOT_EXIT:
+ return MM_RETURN_CODE_NOT_SUPPORTED;
+
+ case TS_RPC_ERROR_INVALID_OPCODE:
+ return MM_RETURN_CODE_INVALID_PARAMETER;
+
+ case TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED:
+ return MM_RETURN_CODE_INVALID_PARAMETER;
+
+ case TS_RPC_ERROR_INVALID_REQ_BODY:
+ return MM_RETURN_CODE_INVALID_PARAMETER;
+
+ case TS_RPC_ERROR_INVALID_RESP_BODY:
+ return MM_RETURN_CODE_INVALID_PARAMETER;
+
+ case TS_RPC_ERROR_RESOURCE_FAILURE:
+ return MM_RETURN_CODE_NOT_SUPPORTED;
+
+ case TS_RPC_ERROR_NOT_READY:
+ return MM_RETURN_CODE_NOT_SUPPORTED;
+
+ case TS_RPC_ERROR_INVALID_TRANSACTION:
+ return MM_RETURN_CODE_INVALID_PARAMETER;
+
+ case TS_RPC_ERROR_INTERNAL:
+ return MM_RETURN_CODE_NOT_SUPPORTED;
+
+ case TS_RPC_ERROR_INVALID_PARAMETER:
+ return MM_RETURN_CODE_INVALID_PARAMETER;
+
+ case TS_RPC_ERROR_INTERFACE_DOES_NOT_EXIST:
+ return MM_RETURN_CODE_NOT_SUPPORTED;
+
+ default:
+ return MM_RETURN_CODE_NOT_SUPPORTED;
+ }
+}
+
+static int32_t smm_var_receive(struct mm_service_interface *iface,
+ struct mm_service_call_req *mm_req)
+{
+ SMM_VARIABLE_COMMUNICATE_HEADER *header = NULL;
+ struct smm_variable_mm_service *service = iface->context;
+ struct call_req rpc_req = { 0 };
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+
+ if (mm_req->req_buf.data_len < SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)
+ return MM_RETURN_CODE_DENIED;
+
+ header = (SMM_VARIABLE_COMMUNICATE_HEADER *)mm_req->req_buf.data;
+
+ rpc_req.opcode = header->Function;
+ rpc_req.req_buf.data = header->Data;
+ rpc_req.req_buf.data_len = mm_req->req_buf.data_len - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+ rpc_req.req_buf.size = mm_req->req_buf.size - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+
+ rpc_req.resp_buf.data = header->Data;
+ rpc_req.resp_buf.data_len = 0;
+ rpc_req.resp_buf.size = mm_req->resp_buf.size - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+
+ rpc_status = service->iface->receive(service->iface, &rpc_req);
+
+ header->ReturnStatus = rpc_req.opstatus;
+
+ if (ADD_OVERFLOW(rpc_req.resp_buf.data_len, SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
+ &mm_req->resp_buf.data_len))
+ return MM_RETURN_CODE_NO_MEMORY;
+
+ if (mm_req->resp_buf.data_len > mm_req->resp_buf.size)
+ return MM_RETURN_CODE_NO_MEMORY;
+
+ return convert_rpc_status(rpc_status);
+}
+
+struct mm_service_interface *smm_variable_mm_service_init(struct smm_variable_mm_service *service,
+ struct rpc_interface *iface)
+{
+ assert(service != NULL);
+ assert(iface != NULL);
+
+ service->iface = iface;
+ service->mm_service.context = service;
+ service->mm_service.receive = smm_var_receive;
+
+ return &service->mm_service;
+}
diff --git a/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.h b/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.h
new file mode 100644
index 000000000..7e1f40ef6
--- /dev/null
+++ b/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef SMM_VARIABLE_MM_SERVICE_H_
+#define SMM_VARIABLE_MM_SERVICE_H_
+
+#include "components/rpc/common/endpoint/rpc_interface.h"
+#include "components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * MM service interface implementation for parsing SMM variable requests and
+ * forwarding them to an RPC interface.
+ */
+
+#define SMM_VARIABLE_GUID \
+ {0xed32d533, 0x99e6, 0x4209, { 0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7 }}
+
+struct smm_variable_mm_service {
+ struct mm_service_interface mm_service;
+ struct rpc_interface *iface;
+};
+
+struct mm_service_interface *smm_variable_mm_service_init(struct smm_variable_mm_service *service,
+ struct rpc_interface *iface);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SMM_VARIABLE_MM_SERVICE_H_ */
diff --git a/protocols/service/smm_variable/parameters.h b/protocols/service/smm_variable/parameters.h
index bc4999eaf..24fab552a 100644
--- a/protocols/service/smm_variable/parameters.h
+++ b/protocols/service/smm_variable/parameters.h
@@ -7,7 +7,8 @@
#ifndef TS_SMM_VARIABLE_PARAMETERS_H
#define TS_SMM_VARIABLE_PARAMETERS_H
-#include <protocols/common/efi/efi_types.h>
+#include "protocols/common/efi/efi_status.h"
+#include "protocols/common/efi/efi_types.h"
/**
* C/C++ definition of smm_variable service parameters
@@ -18,6 +19,18 @@
*/
/**
+ * SMM variable call header
+ */
+typedef struct {
+ uint64_t Function;
+ efi_status_t ReturnStatus;
+ uint8_t Data[1];
+} SMM_VARIABLE_COMMUNICATE_HEADER;
+
+#define SMM_VARIABLE_COMMUNICATE_HEADER_SIZE \
+ offsetof(SMM_VARIABLE_COMMUNICATE_HEADER, Data)
+
+/**
* Variable attributes
*/
#define EFI_VARIABLE_NON_VOLATILE (0x00000001)