Adding test for PSCI_CPU_OFF in primary VM.
Change-Id: I94c750291843a676d1c748c7c7233fff67698435
diff --git a/test/vmapi/primary_only/primary_only.c b/test/vmapi/primary_only/primary_only.c
index ab26f1d..75df306 100644
--- a/test/vmapi/primary_only/primary_only.c
+++ b/test/vmapi/primary_only/primary_only.c
@@ -141,6 +141,63 @@
sl_lock(&lock);
}
+/**
+ * Releases the lock passed in and then stops the CPU.
+ */
+static void vm_cpu_entry_stop(uintptr_t arg)
+{
+ struct spinlock *lock = (struct spinlock *)arg;
+
+ dlog("Second CPU started.\n");
+ sl_unlock(lock);
+
+ dlog("Second CPU stopping.\n");
+ arch_cpu_stop();
+
+ FAIL("arch_cpu_stop() returned.");
+}
+
+/**
+ * Confirm a secondary CPU can be stopped again.
+ */
+TEST(cpus, stop)
+{
+ struct spinlock lock = SPINLOCK_INIT;
+ alignas(4096) static uint8_t other_stack[4096];
+
+ /* Start secondary while holding lock. */
+ sl_lock(&lock);
+ dlog("Starting second CPU.\n");
+ EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(1), other_stack,
+ sizeof(other_stack), vm_cpu_entry_stop,
+ (uintptr_t)&lock),
+ true);
+
+ /* Wait for CPU to release the lock after starting. */
+ sl_lock(&lock);
+
+ dlog("Waiting for second CPU to stop.\n");
+ /* Wait a while for CPU to stop. */
+ while (arch_cpu_status(hftest_get_cpu_id(1)) != POWER_STATUS_OFF) {
+ }
+ dlog("Second CPU stopped.\n");
+
+ dlog("Starting second CPU again.\n");
+ EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(1), other_stack,
+ sizeof(other_stack), vm_cpu_entry_stop,
+ (uintptr_t)&lock),
+ true);
+
+ /* Wait for CPU to release the lock after starting. */
+ sl_lock(&lock);
+
+ dlog("Waiting for second CPU to stop.\n");
+ /* Wait a while for CPU to stop. */
+ while (arch_cpu_status(hftest_get_cpu_id(1)) != POWER_STATUS_OFF) {
+ }
+ dlog("Second CPU stopped.\n");
+}
+
/** Ensures that the Hafnium SPCI version is reported as expected. */
TEST(spci, spci_version)
{