feat(rmm): add support for multiple rec and cpu

Changes to support creating and
executing  multiple rec on multiple cpus.
Added per REC shared buffer between Host and Rec.

Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
Change-Id: Ib6dbd814ee9f68df4a53f9cfdc8b7f9c905c35fe
diff --git a/realm/aarch64/realm_entrypoint.S b/realm/aarch64/realm_entrypoint.S
index e0638f0..73406f9 100644
--- a/realm/aarch64/realm_entrypoint.S
+++ b/realm/aarch64/realm_entrypoint.S
@@ -11,14 +11,20 @@
 	.globl	realm_entrypoint
 
 .section .bss.stacks
-.align 8
-	.fill	REALM_STACK_SIZE
+.align 16
+	.fill	REALM_STACK_SIZE * MAX_REC_COUNT
 stacks_end:
 
 func realm_entrypoint
+	mrs	x0, mpidr_el1
+	mov_imm	x1, MPID_MASK
+	and	x0, x0, x1
+
 	/* Setup the stack pointer. */
-	adr	x1, stacks_end
-	mov	sp, x1
+	bl	realm_setup_my_stack
+
+	/* mpidr 0 is assumed to be primary CPU, jump to warmboot otherwise */
+	cbnz	x0, realm_warmboot_endpoint
 
 	/* Clear BSS */
 	ldr	x0, =__REALM_BSS_START__
@@ -39,9 +45,6 @@
 	sub	x1, x1, x0
 	bl	inv_dcache_range
 
-	/* Initialize architectural state. */
-	bl	arch_init
-
 	/* Relocate symbols */
 pie_fixup:
 	ldr	x0, =pie_fixup
@@ -49,6 +52,10 @@
 	mov	x1, REALM_MAX_LOAD_IMG_SIZE
 	add	x1, x1, x0
 	bl	fixup_gdt_reloc
+
+realm_warmboot_endpoint:
+	/* Initialize architectural state. */
+	bl	arch_init
 #if ENABLE_PAUTH
 	bl	pauth_init_enable
 #endif
@@ -59,6 +66,19 @@
 	b	loop
 endfunc realm_entrypoint
 
+/*
+ * Setup the stack pointer.
+ * x0 = mpidr
+ * clobbers x1,x2
+ */
+func realm_setup_my_stack
+	adr	x1, stacks_end
+	mov	x2, REALM_STACK_SIZE
+	mul	x2, x0, x2
+	sub	sp, x1, x2
+	ret
+endfunc	realm_setup_my_stack
+
 /* Initialize architectural state. */
 func arch_init
 	/* Set the exception vectors. */
diff --git a/realm/realm_debug.c b/realm/realm_debug.c
index e9eb61e..d7989ca 100644
--- a/realm/realm_debug.c
+++ b/realm/realm_debug.c
@@ -19,19 +19,17 @@
  */
 void realm_printf(const char *fmt, ...)
 {
-	host_shared_data_t *guest_shared_data = realm_get_shared_structure();
+	host_shared_data_t *guest_shared_data = realm_get_my_shared_structure();
 	char *log_buffer = (char *)guest_shared_data->log_buffer;
 	va_list args;
 
 	va_start(args, fmt);
-	spin_lock((spinlock_t *)&guest_shared_data->printf_lock);
 	if (strnlen((const char *)log_buffer, MAX_BUF_SIZE) == MAX_BUF_SIZE) {
 		(void)memset((char *)log_buffer, 0, MAX_BUF_SIZE);
 	}
 	(void)vsnprintf((char *)log_buffer +
 			strnlen((const char *)log_buffer, MAX_BUF_SIZE),
 			MAX_BUF_SIZE, fmt, args);
-	spin_unlock((spinlock_t *)&guest_shared_data->printf_lock);
 	va_end(args);
 }
 
@@ -46,18 +44,16 @@
 /* This is used from printf() when crash dump is reached */
 int console_putc(int c)
 {
-	host_shared_data_t *guest_shared_data = realm_get_shared_structure();
+	host_shared_data_t *guest_shared_data = realm_get_my_shared_structure();
 	char *log_buffer = (char *)guest_shared_data->log_buffer;
 
 	if ((c < 0) || (c > 127)) {
 		return -1;
 	}
-	spin_lock((spinlock_t *)&guest_shared_data->printf_lock);
 	if (strnlen((const char *)log_buffer, MAX_BUF_SIZE) == MAX_BUF_SIZE) {
 		(void)memset((char *)log_buffer, 0, MAX_BUF_SIZE);
 	}
 	*((char *)log_buffer + strnlen((const char *)log_buffer, MAX_BUF_SIZE)) = c;
-	spin_unlock((spinlock_t *)&guest_shared_data->printf_lock);
 
 	return c;
 }
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index e867546..586d400 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -25,7 +25,7 @@
  */
 static void realm_sleep_cmd(void)
 {
-	uint64_t sleep = realm_shared_data_get_host_val(HOST_SLEEP_INDEX);
+	uint64_t sleep = realm_shared_data_get_my_host_val(HOST_SLEEP_INDEX);
 
 	realm_printf("Realm: going to sleep for %llums\n", sleep);
 	waitms(sleep);
@@ -64,8 +64,8 @@
 	bool test_succeed = false;
 
 	realm_set_shared_structure((host_shared_data_t *)rsi_get_ns_buffer());
-	if (realm_get_shared_structure() != NULL) {
-		uint8_t cmd = realm_shared_data_get_realm_cmd();
+	if (realm_get_my_shared_structure() != NULL) {
+		uint8_t cmd = realm_shared_data_get_my_realm_cmd();
 
 		switch (cmd) {
 		case REALM_SLEEP_CMD:
diff --git a/realm/realm_shared_data.c b/realm/realm_shared_data.c
index da09b53..2d09f78 100644
--- a/realm/realm_shared_data.c
+++ b/realm/realm_shared_data.c
@@ -5,6 +5,8 @@
  */
 
 #include <string.h>
+#include <arch_helpers.h>
+#include <assert.h>
 #include <host_shared_data.h>
 
 /**
@@ -26,24 +28,34 @@
 /*
  * Get guest mapped shared buffer pointer
  */
-host_shared_data_t *realm_get_shared_structure(void)
+host_shared_data_t *realm_get_my_shared_structure(void)
 {
-	return guest_shared_data;
+	return &guest_shared_data[read_mpidr_el1() & MPID_MASK];
 }
 
 /*
  * Return Host's data at index
  */
-u_register_t realm_shared_data_get_host_val(uint8_t index)
+u_register_t realm_shared_data_get_my_host_val(uint8_t index)
 {
-	return guest_shared_data->host_param_val[(index >= MAX_DATA_SIZE) ?
-		(MAX_DATA_SIZE - 1) : index];
+	assert(index < MAX_DATA_SIZE);
+	return guest_shared_data[read_mpidr_el1() & MPID_MASK].host_param_val[index];
 }
 
 /*
- * Get command sent from Host to realm
+ * Get command sent from Host to this rec
  */
-uint8_t realm_shared_data_get_realm_cmd(void)
+uint8_t realm_shared_data_get_my_realm_cmd(void)
 {
-	return guest_shared_data->realm_cmd;
+	return guest_shared_data[read_mpidr_el1() & MPID_MASK].realm_cmd;
 }
+
+/*
+ * Set data to be shared from this rec to Host
+ */
+void realm_shared_data_set_my_realm_val(uint8_t index, u_register_t val)
+{
+	assert(index < MAX_DATA_SIZE);
+	guest_shared_data[read_mpidr_el1() & MPID_MASK].realm_out_val[index] = val;
+}
+
diff --git a/realm/realm_sve.c b/realm/realm_sve.c
index d5ef8c1..0512789 100644
--- a/realm/realm_sve.c
+++ b/realm/realm_sve.c
@@ -25,7 +25,7 @@
 /* Returns the maximum supported VL. This test is called only by sve Realm */
 bool test_realm_sve_rdvl(void)
 {
-	host_shared_data_t *sd = realm_get_shared_structure();
+	host_shared_data_t *sd = realm_get_my_shared_structure();
 	struct sve_cmd_rdvl *output;
 
 	assert(is_armv8_2_sve_present());
@@ -45,7 +45,7 @@
  */
 bool test_realm_sve_read_id_registers(void)
 {
-	host_shared_data_t *sd = realm_get_shared_structure();
+	host_shared_data_t *sd = realm_get_my_shared_structure();
 	struct sve_cmd_id_regs *output;
 
 	output = (struct sve_cmd_id_regs *)sd->realm_cmd_output_buffer;
@@ -65,7 +65,7 @@
  */
 bool test_realm_sve_probe_vl(void)
 {
-	host_shared_data_t *sd = realm_get_shared_structure();
+	host_shared_data_t *sd = realm_get_my_shared_structure();
 	struct sve_cmd_probe_vl *output;
 
 	assert(is_armv8_2_sve_present());