Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2023, Arm Limited. All rights reserved. |
| 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | * |
| 6 | */ |
| 7 | |
| 8 | #include <stdio.h> |
| 9 | |
| 10 | #include <arch_features.h> |
| 11 | #include <arch_helpers.h> |
| 12 | #include <debug.h> |
| 13 | #include <fpu.h> |
| 14 | #include <host_realm_helper.h> |
| 15 | #include <host_shared_data.h> |
| 16 | #include <psci.h> |
| 17 | #include "realm_def.h" |
| 18 | #include <realm_rsi.h> |
| 19 | #include <realm_tests.h> |
| 20 | #include <realm_psci.h> |
| 21 | #include <tftf_lib.h> |
| 22 | |
| 23 | #define CXT_ID_MAGIC 0x100 |
| 24 | static uint64_t is_secondary_cpu_booted; |
Shruti Gupta | affbae8 | 2023-08-22 12:51:11 +0100 | [diff] [blame] | 25 | static spinlock_t lock; |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 26 | |
| 27 | static void rec1_handler(u_register_t cxt_id) |
| 28 | { |
Shruti Gupta | a276b20 | 2023-12-18 10:07:43 +0000 | [diff] [blame] | 29 | realm_printf("running on CPU = 0x%lx cxt_id= 0x%lx\n", |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 30 | read_mpidr_el1() & MPID_MASK, cxt_id); |
| 31 | if (cxt_id < CXT_ID_MAGIC || cxt_id > CXT_ID_MAGIC + MAX_REC_COUNT) { |
Shruti Gupta | a276b20 | 2023-12-18 10:07:43 +0000 | [diff] [blame] | 32 | realm_printf("Wrong cxt_id\n"); |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 33 | rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD); |
| 34 | } |
Shruti Gupta | affbae8 | 2023-08-22 12:51:11 +0100 | [diff] [blame] | 35 | spin_lock(&lock); |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 36 | is_secondary_cpu_booted++; |
Shruti Gupta | affbae8 | 2023-08-22 12:51:11 +0100 | [diff] [blame] | 37 | spin_unlock(&lock); |
Shruti Gupta | 24597d1 | 2023-10-02 10:40:19 +0100 | [diff] [blame] | 38 | realm_cpu_off(); |
| 39 | } |
| 40 | |
| 41 | static void rec2_handler(u_register_t cxt_id) |
| 42 | { |
| 43 | rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD); |
| 44 | } |
| 45 | |
| 46 | bool test_realm_multiple_rec_psci_denied_cmd(void) |
| 47 | { |
| 48 | u_register_t ret; |
| 49 | |
| 50 | is_secondary_cpu_booted = 0U; |
| 51 | ret = realm_cpu_on(1U, (uintptr_t)rec1_handler, 0x100); |
| 52 | if (ret != PSCI_E_DENIED) { |
| 53 | return false; |
| 54 | } |
| 55 | |
| 56 | if (is_secondary_cpu_booted != 0U) { |
| 57 | rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD); |
| 58 | } |
| 59 | |
| 60 | ret = realm_psci_affinity_info(1U, MPIDR_AFFLVL0); |
| 61 | if (ret != PSCI_STATE_OFF) { |
| 62 | realm_printf("CPU 1 should have been off\n"); |
| 63 | return false; |
| 64 | } |
| 65 | |
| 66 | ret = realm_cpu_on(2U, (uintptr_t)rec2_handler, 0x102); |
| 67 | if (ret != PSCI_E_ALREADY_ON) { |
| 68 | realm_printf("CPU 2 should have been already on\n"); |
| 69 | return false; |
| 70 | } |
| 71 | return true; |
| 72 | } |
Shruti Gupta | affbae8 | 2023-08-22 12:51:11 +0100 | [diff] [blame] | 73 | |
| 74 | bool test_realm_multiple_rec_multiple_cpu_cmd(void) |
| 75 | { |
| 76 | unsigned int i = 1U, rec_count; |
| 77 | u_register_t ret; |
| 78 | |
| 79 | realm_printf("Realm: running on CPU = 0x%lx\n", read_mpidr_el1() & MPID_MASK); |
| 80 | rec_count = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX); |
| 81 | |
| 82 | /* Check CPU_ON is supported */ |
| 83 | ret = realm_psci_features(SMC_PSCI_CPU_ON); |
| 84 | if (ret != PSCI_E_SUCCESS) { |
| 85 | realm_printf("SMC_PSCI_CPU_ON not supported\n"); |
| 86 | return false; |
| 87 | } |
| 88 | |
| 89 | for (unsigned int j = 1U; j < rec_count; j++) { |
| 90 | ret = realm_cpu_on(j, (uintptr_t)rec1_handler, CXT_ID_MAGIC + j); |
| 91 | if (ret != PSCI_E_SUCCESS) { |
| 92 | realm_printf("SMC_PSCI_CPU_ON failed %d.\n", j); |
| 93 | return false; |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | /* Exit to host to allow host to run all CPUs */ |
| 98 | rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD); |
| 99 | /* wait for all CPUs to come up */ |
| 100 | while (is_secondary_cpu_booted != rec_count - 1U) { |
| 101 | waitms(200); |
| 102 | } |
| 103 | |
| 104 | /* wait for all CPUs to turn off */ |
| 105 | while (i < rec_count) { |
| 106 | ret = realm_psci_affinity_info(i, MPIDR_AFFLVL0); |
| 107 | if (ret != PSCI_STATE_OFF) { |
| 108 | /* wait and query again */ |
| 109 | realm_printf(" CPU %d is not off\n", i); |
| 110 | waitms(200); |
| 111 | continue; |
| 112 | } |
| 113 | i++; |
| 114 | } |
| 115 | realm_printf("All CPU are off\n"); |
| 116 | return true; |
| 117 | } |