feat(versal-net): add support for IPI

Add support to send IPI to firmware.

Signed-off-by: Michal Simek <michal.simek@amd.com>
Signed-off-by: Akshay Belsare <Akshay.Belsare@amd.com>
Change-Id: I8cd54c05b6a726e0d398dfc1cdcc7f4cf09ba725
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_common.c b/plat/xilinx/versal_net/aarch64/versal_net_common.c
index 416121c..46ebc3e 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_common.c
+++ b/plat/xilinx/versal_net/aarch64/versal_net_common.c
@@ -12,6 +12,7 @@
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
+#include <plat_ipi.h>
 
 #include <plat_private.h>
 #include <versal_net_def.h>
@@ -28,6 +29,7 @@
 	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(DEVICE2_BASE, DEVICE2_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(CRF_BASE, CRF_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(IPI_BASE, IPI_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	{ 0 }
 };
 
diff --git a/plat/xilinx/versal_net/include/plat_ipi.h b/plat/xilinx/versal_net/include/plat_ipi.h
new file mode 100644
index 0000000..5255f8f
--- /dev/null
+++ b/plat/xilinx/versal_net/include/plat_ipi.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Versal IPI management enums and defines */
+
+#ifndef PLAT_IPI_H
+#define PLAT_IPI_H
+
+#include <stdint.h>
+
+#include <ipi.h>
+
+/*********************************************************************
+ * IPI agent IDs macros
+ ********************************************************************/
+#define IPI_ID_PMC	1U
+#define IPI_ID_APU	2U
+#define IPI_ID_RPU0	3U
+#define IPI_ID_RPU1	4U
+#define IPI_ID_3	5U
+#define IPI_ID_4	6U
+#define IPI_ID_5	7U
+#define IPI_ID_MAX	8U
+
+/*********************************************************************
+ * IPI message buffers
+ ********************************************************************/
+#define IPI_BUFFER_BASEADDR	(0xEB3F0000U)
+
+#define IPI_BUFFER_APU_BASE	(IPI_BUFFER_BASEADDR + 0x400U)
+#define IPI_BUFFER_PMC_BASE	(IPI_BUFFER_BASEADDR + 0x200U)
+
+#define IPI_BUFFER_TARGET_APU_OFFSET	0x80U
+#define IPI_BUFFER_TARGET_PMC_OFFSET	0x40U
+
+#define IPI_BUFFER_LOCAL_BASE	IPI_BUFFER_APU_BASE
+#define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMC_BASE
+
+#define IPI_BUFFER_TARGET_LOCAL_OFFSET	IPI_BUFFER_TARGET_APU_OFFSET
+#define IPI_BUFFER_TARGET_REMOTE_OFFSET	IPI_BUFFER_TARGET_PMC_OFFSET
+
+#define IPI_BUFFER_MAX_WORDS	8
+
+#define IPI_BUFFER_REQ_OFFSET	0x0U
+#define IPI_BUFFER_RESP_OFFSET	0x20U
+
+/*********************************************************************
+ * Platform specific IPI API declarations
+ ********************************************************************/
+
+/* Configure IPI table for versal_net */
+void versal_net_ipi_config_table_init(void);
+
+#endif /* PLAT_IPI_H */
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index c2dab92..9b80683 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -77,6 +77,8 @@
 #define DEVICE2_SIZE		U(0x01000000)
 #define CRF_BASE		U(0xFD1A0000)
 #define CRF_SIZE		U(0x00600000)
+#define IPI_BASE		U(0xEB300000)
+#define IPI_SIZE		U(0x00100000)
 
 /* CRL */
 #define VERSAL_NET_CRL					U(0xEB5E0000)
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index 32594c7..f361dfe 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -46,6 +46,7 @@
 
 PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
 				-Iplat/xilinx/common/include/			\
+				-Iplat/xilinx/common/ipi_mailbox_service/	\
 				-I${PLAT_PATH}/include/				\
 				-Iplat/xilinx/versal/pm_service/
 
@@ -70,6 +71,8 @@
 				plat/common/plat_psci_common.c			\
 				${PLAT_PATH}/plat_psci.c			\
 				plat/xilinx/common/plat_startup.c		\
+				plat/xilinx/common/ipi.c			\
+				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
 				${PLAT_PATH}/bl31_versal_net_setup.c		\
 				${PLAT_PATH}/plat_topology.c			\
 				common/fdt_fixup.c				\
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index 9a8d519..0e3940f 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -14,6 +14,7 @@
 #include <common/runtime_svc.h>
 #include <tools_share/uuid.h>
 
+#include "ipi_mailbox_svc.h"
 #include "plat_private.h"
 #include "pm_svc_main.h"
 
@@ -26,6 +27,13 @@
 #define SIP_SVC_VERSION_MAJOR		(0U)
 #define SIP_SVC_VERSION_MINOR		(1U)
 
+/* These macros are used to identify PM calls from the SMC function ID */
+#define PM_FID_MASK	0xf000u
+#define PM_FID_VALUE	0u
+#define IPI_FID_VALUE	0x1000u
+#define is_pm_fid(_fid)	(((_fid) & PM_FID_MASK) == PM_FID_VALUE)
+#define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE)
+
 /* SiP Service UUID */
 DEFINE_SVC_UUID2(versal_net_sip_uuid,
 		0x80d4c25a, 0xebaf, 0x11eb, 0x94, 0x68,
@@ -55,6 +63,17 @@
 			     u_register_t flags)
 {
 	/* Let PM SMC handler deal with PM-related requests */
+	if (is_pm_fid(smc_fid)) {
+		return smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
+				flags);
+	}
+
+	/* Let IPI SMC handler deal with IPI-related requests if platform */
+	if (is_ipi_fid(smc_fid)) {
+		return ipi_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+	}
+
+	/* Let PM SMC handler deal with PM-related requests */
 	switch (smc_fid) {
 	case VERSAL_NET_SIP_SVC_CALL_COUNT:
 		/* PM functions + default functions */