Add MHUv3 adapter

Use an MHUv3 adapter to forward the calls to the MHU wrapper.

Also remove const from MHUv3 struct's base address so it
can be changed in runtime.

Change-Id: I3ef943716a73081e6386c1ec7b80e255a12ecc91
Signed-off-by: Ziad Elhanafy <ziad.elhanafy@arm.com>
diff --git a/platform/drivers/arm/mhu_driver/mhu_v3_x/driver.cmake b/platform/drivers/arm/mhu_driver/mhu_v3_x/driver.cmake
new file mode 100644
index 0000000..9f27042
--- /dev/null
+++ b/platform/drivers/arm/mhu_driver/mhu_v3_x/driver.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Add source files for using mhu driver
+target_sources(${TGT}
+	PRIVATE
+		"${CMAKE_CURRENT_LIST_DIR}/mhu_v3_x.c"
+		"${CMAKE_CURRENT_LIST_DIR}/mhu_wrapper_v3_x.c"
+		"${CMAKE_CURRENT_LIST_DIR}/mhu_adapter_v3_x.c"
+)
diff --git a/platform/drivers/arm/mhu_driver/mhu_v3_x/mhu.h b/platform/drivers/arm/mhu_driver/mhu_v3_x/mhu.h
index 2289085..bc12a3f 100644
--- a/platform/drivers/arm/mhu_driver/mhu_v3_x/mhu.h
+++ b/platform/drivers/arm/mhu_driver/mhu_v3_x/mhu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024 Arm Limited. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,18 +25,12 @@
 extern "C" {
 #endif
 
-#if TFM_UNIQUE_ERROR_CODES == 1
-#include "error_codes_mapping.h"
-#else
-#define MHU_ERROR_BASE 0x1u
-#endif /* TFM_UNIQUE_ERROR_CODES */
-
 /**
  * Generic MHU error enumeration types.
  */
 enum mhu_error_t {
     MHU_ERR_NONE =  0,
-    MHU_ERR_SIGNAL_WAIT_CLEAR_INVALID_ARG = MHU_ERROR_BASE,
+    MHU_ERR_SIGNAL_WAIT_CLEAR_INVALID_ARG,
     MHU_ERR_WAIT_SIGNAL_CLEAR_INVALID_ARG,
     MHU_ERR_CLEAR_WAIT_SIGNAL_INVALID_ARG,
     MHU_ERR_VALIDATE_BUFFER_PARAMS_INVALID_ARG,
diff --git a/platform/drivers/arm/mhu_driver/mhu_v3_x/mhu_adapter_v3_x.c b/platform/drivers/arm/mhu_driver/mhu_v3_x/mhu_adapter_v3_x.c
new file mode 100644
index 0000000..4a825ff
--- /dev/null
+++ b/platform/drivers/arm/mhu_driver/mhu_v3_x/mhu_adapter_v3_x.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <config/interface/config_store.h>
+#include <platform/interface/device_region.h>
+#include <platform/interface/mhu_interface.h>
+#include <stdlib.h>
+
+#include "mhu.h"
+#include "mhu_v3_x.h"
+
+static int mhu_adapter_send(void *context, unsigned char *send_buffer, size_t size)
+{
+	struct mhu_v3_x_dev_t *dev = NULL;
+
+	if (!context || !send_buffer || size == 0)
+		return -1;
+
+	dev = (struct mhu_v3_x_dev_t *)context;
+
+	if (mhu_send_data(dev, (uint8_t *)send_buffer, size) != MHU_ERR_NONE)
+		return -1;
+
+	return 0;
+}
+
+static int mhu_adapter_receive(void *context, unsigned char *receive_buffer, size_t *size)
+{
+	struct mhu_v3_x_dev_t *dev = NULL;
+
+	if (!context || !receive_buffer || !size)
+		return -1;
+
+	dev = (struct mhu_v3_x_dev_t *)context;
+
+	if (mhu_receive_data(dev, (uint8_t *)receive_buffer, size) != MHU_ERR_NONE)
+		return -1;
+
+	return 0;
+}
+
+static int mhu_adapter_wait_data(void *context)
+{
+	struct mhu_v3_x_dev_t *dev = NULL;
+
+	if (!context)
+		return -1;
+
+	dev = (struct mhu_v3_x_dev_t *)context;
+
+	if (mhu_wait_data(dev) != MHU_ERR_NONE)
+		return -1;
+
+	return 0;
+}
+
+static int mhu_adapter_signal_and_wait_for_clear(void *context, uint32_t value)
+{
+	struct mhu_v3_x_dev_t *dev = NULL;
+
+	if (!context)
+		return -1;
+
+	dev = (struct mhu_v3_x_dev_t *)context;
+
+	if (signal_and_wait_for_clear(dev, value) != MHU_ERR_NONE)
+		return -1;
+
+	return 0;
+}
+
+static int mhu_adapter_wait_for_signal_and_clear(void *context, uint32_t value)
+{
+	struct mhu_v3_x_dev_t *dev = NULL;
+
+	if (!context)
+		return -1;
+
+	dev = (struct mhu_v3_x_dev_t *)context;
+
+	if (wait_for_signal_and_clear(dev, value) == MHU_ERR_NONE)
+		return -1;
+
+	return 0;
+}
+
+int platform_mhu_create(struct platform_mhu_driver *driver, const char *object_name,
+			bool is_receiver)
+{
+	struct mhu_v3_x_dev_t *new_instance = NULL;
+	enum mhu_error_t status = MHU_ERR_NONE;
+	struct device_region device_region = { 0 };
+	static const struct platform_mhu_iface iface = {
+		.send = mhu_adapter_send,
+		.receive = mhu_adapter_receive,
+		.wait_data = mhu_adapter_wait_data,
+		.signal_and_wait_for_clear = mhu_adapter_signal_and_wait_for_clear,
+		.wait_for_signal_and_clear = mhu_adapter_wait_for_signal_and_clear,
+	};
+
+	if (!driver || !object_name)
+		return -1;
+
+	/* Default to leaving the driver in a safe but inoperable state. */
+	driver->iface = &iface;
+	driver->context = NULL;
+
+	if (!config_store_query(CONFIG_CLASSIFIER_DEVICE_REGION, object_name, 0, &device_region,
+				sizeof(device_region)))
+		return -1;
+
+	new_instance = calloc(1, sizeof(struct mhu_v3_x_dev_t));
+	if (!new_instance)
+		return -1;
+
+	new_instance->base = device_region.base_addr;
+
+	if (is_receiver) {
+		new_instance->frame = MHU_V3_X_MBX_FRAME;
+		status = mhu_init_receiver(new_instance);
+	} else {
+		new_instance->frame = MHU_V3_X_PBX_FRAME;
+		status = mhu_init_sender(new_instance);
+	}
+
+	if (status != MHU_ERR_NONE) {
+		free(new_instance);
+		return -1;
+	}
+
+	driver->context = new_instance;
+
+	return 0;
+}
+
+void platform_mhu_destroy(struct platform_mhu_driver *driver)
+{
+	if (!driver || !driver->context)
+		return;
+
+	free(driver->context);
+	driver->context = NULL;
+}
diff --git a/platform/drivers/arm/mhu_driver/mhu_v3_x/mhu_v3_x.h b/platform/drivers/arm/mhu_driver/mhu_v3_x/mhu_v3_x.h
index f369f36..b3e76da 100644
--- a/platform/drivers/arm/mhu_driver/mhu_v3_x/mhu_v3_x.h
+++ b/platform/drivers/arm/mhu_driver/mhu_v3_x/mhu_v3_x.h
@@ -30,12 +30,6 @@
 extern "C" {
 #endif
 
-#if TFM_UNIQUE_ERROR_CODES == 1
-#include "error_codes_mapping.h"
-#else
-#define MHU_V_3_X_ERROR_BASE 0x1u
-#endif /* TFM_UNIQUE_ERROR_CODES */
-
 /* MHU Architecture Major Revision 3 */
 #define MHU_MAJOR_REV_V3 (0x2u)
 /* MHU Architecture Minor Revision 0 */
@@ -63,7 +57,7 @@
     /* No error */
     MHU_V_3_X_ERR_NONE = 0x0u,
     /* Invalid input param in init function */
-    MHU_V_3_X_ERR_INIT_INVALID_PARAM = MHU_V_3_X_ERROR_BASE,
+    MHU_V_3_X_ERR_INIT_INVALID_PARAM,
     /* MHU Revision not supported error */
     MHU_V_3_X_ERR_INIT_UNSUPPORTED_VERSION,
     /* Invalid input param in get_num_channel function */
@@ -123,7 +117,7 @@
  */
 struct mhu_v3_x_dev_t {
     /* Base address of the MHUv3 frame */
-    const uintptr_t base;
+    uintptr_t base;
     /* Type of the MHUv3 frame */
     enum mhu_v3_x_frame_t frame;
     /* Minor revision of the MHUv3 */