Skip to content

Commit

Permalink
fix(unittests): sysregs status might be inconsistent between runs
Browse files Browse the repository at this point in the history
Current implementation of test_helpers_rmm_start() in the
test_helpers library performs an initialization of the RMM runtime
for the host build on the first call. Subsequent calls are just
ignored after the first initialization.

This can cause a number of problems due to the sysregs left in
an undetermined status. For instance, a test using the RMM
runtime will leave the sysreg in an inconsistent state and cause
problems for the next test one. Hence it is essential for the
next test to reset to a previous known state as part of
initialization. Any test  using the RMM runtime will need to
restore the sysregs status and callbacks before running any new test.

This patch adds support to save the sysreg state after RMM
initialization in test_helpers_rmm_start() and restores this
state for any subsequent call to test_helpers_rmm_start().

Signed-off-by: Javier Almansa Sobrino <[email protected]>
Change-Id: Ifb705380f079308576e7f59b475be6984447f045
  • Loading branch information
javieralso-arm committed Mar 22, 2023
1 parent f450817 commit 48d68a7
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
19 changes: 17 additions & 2 deletions plat/host/common/include/host_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#ifndef HOST_UTILS_H
#define HOST_UTILS_H

#include <stddef.h>
#include <types.h>

/***********************************************************************
Expand Down Expand Up @@ -113,9 +114,23 @@ int host_util_set_sysreg_cb(char *name, rd_cb_t rd_cb, wr_cb_t wr_cb,
int host_util_set_default_sysreg_cb(char *name, u_register_t init);

/*
* Clear the list of sysreg callbacks.
* Save the sysreg state across all PEs in the system along with registered
* callbacks. This function must only be used during RMM runtime bring-up,
* at a point wherein the system is initialized properly and can restored
* for later test iterations.
*/
void host_util_reset_all_sysreg_cb(void);
void host_util_take_sysreg_snapshot(void);

/*
* Restore a saved sysreg state and associated callbacks. The state is already
* assumed to be saved prior to calling this API.
*/
void host_util_restore_sysreg_snapshot(void);

/*
* Zero all sysreg values and unregister all sysreg callbacks.
*/
void host_util_zero_sysregs_and_cbs(void);

/*
* Return the configured address for the granule base.
Expand Down
15 changes: 14 additions & 1 deletion plat/host/common/src/host_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <xlat_tables.h>

static struct sysreg_data sysregs[SYSREG_MAX_CBS];
static struct sysreg_data sysregs_snapshot[SYSREG_MAX_CBS];
static unsigned int installed_cb_idx;
static unsigned int current_cpuid;

Expand Down Expand Up @@ -100,7 +101,19 @@ int host_util_set_sysreg_cb(char *name, rd_cb_t rd_cb, wr_cb_t wr_cb,
return -ENOMEM;
}

void host_util_reset_all_sysreg_cb(void)
void host_util_take_sysreg_snapshot(void)
{
memcpy((void *)&sysregs_snapshot[0], (void *)&sysregs[0],
sizeof(struct sysreg_data) * SYSREG_MAX_CBS);
}

void host_util_restore_sysreg_snapshot(void)
{
memcpy((void *)&sysregs[0], (void *)&sysregs_snapshot[0],
sizeof(struct sysreg_data) * SYSREG_MAX_CBS);
}

void host_util_zero_sysregs_and_cbs(void)
{

(void)memset((void *)sysregs, 0,
Expand Down
6 changes: 6 additions & 0 deletions plat/host/host_test/src/test_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,14 @@ void test_helpers_rmm_start(bool secondaries)
start_secondary_pe(i);
}
host_util_set_cpuid(0U);

/* Take a snapshot of the current sysreg status */
host_util_take_sysreg_snapshot();
}
initialized = true;
} else {
/* Restore the sysreg status */
host_util_restore_sysreg_snapshot();
}
}

Expand Down

0 comments on commit 48d68a7

Please sign in to comment.