fix(realm): fix calculation of Realm's REC index
This patch fixes the issues related to the calculation of
Realm's REC index based on the read value of MPIDR_EL1 register
and REC's mpidr parameter from the REC's index.
RMM reports MPIDR_EL1.Aff0 field matching RmiRecMpidr type
with [7:4] bits RES0, making MPIDR_EL1=0x80000100 represent
REC 16, but not 256 as it is implemented in the existing code.
The patch adds the following macros:
- RMI_REC_MPIDR(idx) which calculates RmiRecMpidr value based
on REC index.
- REC_IDX(mpidr) gets REC index from MPIDR_EL1.
Change-Id: Ieac473984f3a50d2815dcfe8d291d31bd70ebae7
Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
diff --git a/realm/aarch64/realm_entrypoint.S b/realm/aarch64/realm_entrypoint.S
index 1aff61e..7e535bb 100644
--- a/realm/aarch64/realm_entrypoint.S
+++ b/realm/aarch64/realm_entrypoint.S
@@ -19,8 +19,21 @@
/* Save x0 - context_id */
mov x20, x0
mrs x0, mpidr_el1
- mov_imm x1, MPID_MASK
- and x0, x0, x1
+
+ /*
+ * Convert MPIDR_EL1 register type value
+ * Aff3[39:32].Aff2[23:16].Aff1[15:8].RES0[7:4].Aff0[3:0]
+ * to REC linear index
+ * Aff3[27:20].Aff2[19:12].Aff1[11:4].Aff0[3:0].
+ */
+ and x1, x0, #(MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT) /* 0xff00000000 */
+ and x0, x0, #((MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT) | \
+ (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT) | \
+ (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)) /* 0xffffff */
+ orr x1, x0, x1, lsr #(MPIDR_AFF3_SHIFT - MPIDR_AFF2_SHIFT - \
+ MPIDR_AFF1_SHIFT - MPIDR_AFF0_SHIFT) /* 8 */
+ and x0, x0, #MPIDR_AFFLVL_MASK /* 0xff */
+ orr x0, x0, x1, lsr #(MPIDR_AFF1_SHIFT - RMI_MPIDR_AFF0_WIDTH) /* 4 */
/* Setup the stack pointer */
bl realm_setup_my_stack
diff --git a/realm/realm_rsi.c b/realm/realm_rsi.c
index 04f57fc..cd4342f 100644
--- a/realm/realm_rsi.c
+++ b/realm/realm_rsi.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -47,7 +47,7 @@
struct rsi_host_call host_cal __aligned(sizeof(struct rsi_host_call));
host_cal.imm = exit_code;
- host_cal.gprs[0] = read_mpidr_el1() & MPID_MASK;
+ host_cal.gprs[0] = read_mpidr_el1();
tftf_smc(&(smc_args) {RSI_HOST_CALL, (u_register_t)&host_cal,
0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
}
diff --git a/realm/realm_shared_data.c b/realm/realm_shared_data.c
index 2d09f78..2825796 100644
--- a/realm/realm_shared_data.c
+++ b/realm/realm_shared_data.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +8,7 @@
#include <arch_helpers.h>
#include <assert.h>
#include <host_shared_data.h>
+#include <realm_def.h>
/**
* @brief - Returns the base address of the shared region
@@ -30,7 +31,7 @@
*/
host_shared_data_t *realm_get_my_shared_structure(void)
{
- return &guest_shared_data[read_mpidr_el1() & MPID_MASK];
+ return &guest_shared_data[REC_IDX(read_mpidr_el1())];
}
/*
@@ -39,7 +40,7 @@
u_register_t realm_shared_data_get_my_host_val(uint8_t index)
{
assert(index < MAX_DATA_SIZE);
- return guest_shared_data[read_mpidr_el1() & MPID_MASK].host_param_val[index];
+ return guest_shared_data[REC_IDX(read_mpidr_el1())].host_param_val[index];
}
/*
@@ -47,7 +48,7 @@
*/
uint8_t realm_shared_data_get_my_realm_cmd(void)
{
- return guest_shared_data[read_mpidr_el1() & MPID_MASK].realm_cmd;
+ return guest_shared_data[REC_IDX(read_mpidr_el1())].realm_cmd;
}
/*
@@ -56,6 +57,6 @@
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;
+ guest_shared_data[REC_IDX(read_mpidr_el1())].realm_out_val[index] = val;
}