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());