Add log provider component
Add component for handling logging RPC calls from SPs.
Signed-off-by: Gabor Toth <gabor.toth2@arm.com>
Signed-off-by: Gabor Ambrus <gabor.ambrus@arm.com>
Change-Id: I6d09bac2c77eaff1356e2d8f0d0883aa7803b998
diff --git a/components/service/log/backend/log_backend.h b/components/service/log/backend/log_backend.h
new file mode 100644
index 0000000..2ac4c33
--- /dev/null
+++ b/components/service/log/backend/log_backend.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef LOG_BACKEND_H
+#define LOG_BACKEND_H
+
+#include "components/service/log/common/log_status.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Common log backend interface
+ *
+ * A concrete log backend provides an implementation of this
+ * interface.
+ */
+struct log_backend_interface {
+ /**
+ * \brief Processes the character sequence (str) in a desired way (e.g. print to UART).
+ *
+ * \param[in] context The concrete backend context
+ * \param[in] str Character sequence to be printed (null-terminated)
+ */
+ log_status_t (*puts)(void *context, const char *str);
+};
+
+/**
+ * \brief Common log backend instance
+ */
+struct log_backend {
+ /**
+ * \brief The backend context
+ *
+ * Points to backend specific instance data.
+ */
+ void *context;
+
+ /**
+ * \brief The backend interface
+ *
+ * A concrete backend provides an implementation of this interface.
+ */
+ const struct log_backend_interface *interface;
+};
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LOG_BACKEND_H */
diff --git a/components/service/log/common/log_status.h b/components/service/log/common/log_status.h
new file mode 100644
index 0000000..1fca78e
--- /dev/null
+++ b/components/service/log/common/log_status.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LOG_STATUS_H
+#define LOG_STATUS_H
+
+#include <stdint.h>
+
+typedef int32_t log_status_t;
+
+#define LOG_STATUS_SUCCESS ((log_status_t)0)
+#define LOG_STATUS_GENERIC_ERROR ((log_status_t)-1)
+#define LOG_STATUS_INVALID_PARAMETER ((log_status_t)-2)
+
+#endif /* LOG_STATUS_H */
diff --git a/components/service/log/provider/component.cmake b/components/service/log/provider/component.cmake
new file mode 100644
index 0000000..c5d043e
--- /dev/null
+++ b/components/service/log/provider/component.cmake
@@ -0,0 +1,19 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, 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}/log_provider.c"
+ )
+
+
+target_include_directories(${TGT}
+ PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}"
+ )
diff --git a/components/service/log/provider/log_provider.c b/components/service/log/provider/log_provider.c
new file mode 100644
index 0000000..8d5e5f9
--- /dev/null
+++ b/components/service/log/provider/log_provider.c
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include "log_provider.h"
+
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
+#include "components/service/log/common/log_status.h"
+#include "log_uuid.h"
+#include "protocols/rpc/common/packed-c/status.h"
+#include "protocols/service/log/packed-c/log_proto.h"
+#include "util.h"
+
+static rpc_status_t log_puts_handler(void *context, struct rpc_request *req);
+
+static const struct service_handler handler_table[] = { { TS_LOG_OPCODE_PUTS, log_puts_handler } };
+
+struct rpc_service_interface *log_provider_init(struct log_provider *context,
+ struct log_backend *backend)
+{
+ const struct rpc_uuid service_uuid = { .uuid = TS_LOG_SERVICE_UUID };
+
+ if (context == NULL || backend == NULL)
+ return NULL;
+
+ service_provider_init(&context->base_provider, context, &service_uuid, handler_table,
+ ARRAY_SIZE(handler_table));
+
+ context->backend = backend;
+
+ return service_provider_get_rpc_interface(&context->base_provider);
+}
+
+/*
+ * Handler function for provider to call puts operation of the attached backend.
+ */
+static rpc_status_t log_puts_handler(void *context, struct rpc_request *req)
+{
+ struct log_provider *this_context = (struct log_provider *)context;
+ struct log_request *request_desc = NULL;
+ size_t request_data_length = 0;
+
+ /* Checking if the descriptor fits into the request buffer */
+ if (req->request.data_length < sizeof(struct log_request))
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+
+ request_desc = (struct log_request *)(req->request.data);
+
+ /* Checking for overflow */
+ if (ADD_OVERFLOW(sizeof(*request_desc), request_desc->msg_length, &request_data_length))
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+
+ /* Checking if descriptor and data fits into the request buffer */
+ if (req->request.data_length < request_data_length)
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+
+ /* Make sure it is null terminated */
+ if (request_desc->msg_length != 0)
+ request_desc->msg[request_desc->msg_length - 1] = '\0';
+
+ this_context->backend->interface->puts(this_context->backend->context, request_desc->msg);
+ req->service_status = LOG_STATUS_SUCCESS;
+
+ return RPC_SUCCESS;
+}
diff --git a/components/service/log/provider/log_provider.h b/components/service/log/provider/log_provider.h
new file mode 100644
index 0000000..ec1c7f9
--- /dev/null
+++ b/components/service/log/provider/log_provider.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LOG_PROVIDER_H
+#define LOG_PROVIDER_H
+
+#include "components/service/common/provider/service_provider.h"
+#include "service/log/backend/log_backend.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct log_provider {
+ struct service_provider base_provider;
+ struct log_backend *backend;
+};
+
+struct rpc_service_interface *log_provider_init(struct log_provider *context,
+ struct log_backend *backend);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LOG_PROVIDER_H */
diff --git a/components/service/log/provider/log_uuid.h b/components/service/log/provider/log_uuid.h
new file mode 100644
index 0000000..1d5d1d1
--- /dev/null
+++ b/components/service/log/provider/log_uuid.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef LOG_UUID_H
+#define LOG_UUID_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define TS_LOG_SERVICE_UUID \
+{ 0xda, 0x9d, 0xff, 0xbd, 0xd5, 0x90, 0x40, 0xed, 0x97, 0x5f, 0x19, 0xc6, 0x5a, 0x3d, 0x52, 0xd3 }
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* LOG_UUID_H */
\ No newline at end of file
diff --git a/protocols/service/log/packed-c/component.cmake b/protocols/service/log/packed-c/component.cmake
new file mode 100644
index 0000000..8fa3490
--- /dev/null
+++ b/protocols/service/log/packed-c/component.cmake
@@ -0,0 +1,16 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, 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_include_directories(${TGT}
+ PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}"
+ )
diff --git a/protocols/service/log/packed-c/log_proto.h b/protocols/service/log/packed-c/log_proto.h
new file mode 100644
index 0000000..54f6420
--- /dev/null
+++ b/protocols/service/log/packed-c/log_proto.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LOG_PROTO_H
+#define LOG_PROTO_H
+
+#include <stdint.h>
+
+struct __attribute__ ((__packed__)) log_request {
+ uint64_t msg_length;
+ char msg[];
+};
+
+/* Opcodes */
+#define TS_LOG_OPCODE_BASE (0x0100)
+#define TS_LOG_OPCODE_PUTS (TS_LOG_OPCODE_BASE + 1)
+
+#endif /* LOG_PROTO_H */