Jayanth Dodderi Chidanand | cd6c94b | 2022-02-15 17:19:05 +0000 | [diff] [blame] | 1 | /* |
Boyan Karatotev | 8f17515 | 2025-06-23 16:18:03 +0100 | [diff] [blame^] | 2 | * Copyright (c) 2024-2025, Arm Limited. All rights reserved. |
Jayanth Dodderi Chidanand | cd6c94b | 2022-02-15 17:19:05 +0000 | [diff] [blame] | 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | */ |
| 6 | |
| 7 | #include "./test_ls64.h" |
| 8 | #include <test_helpers.h> |
| 9 | |
| 10 | /* |
| 11 | * @brief Test LS64 feature support when the extension is enabled. |
| 12 | * |
| 13 | * Execute the LS64 instructions: |
| 14 | * LD64B - single-copy atomic 64-byte load. |
| 15 | * ST64B - single-copy atomic 64-byte store without return. |
| 16 | * |
| 17 | * These instructions should not be trapped to EL3, when EL2 access them. |
| 18 | * |
| 19 | * @return test_result_t |
| 20 | */ |
| 21 | test_result_t test_ls64_instructions(void) |
| 22 | { |
| 23 | #if PLAT_fvp |
| 24 | #ifdef __aarch64__ |
| 25 | |
| 26 | /* Make sure FEAT_LS64 is supported. */ |
| 27 | SKIP_TEST_IF_LS64_NOT_SUPPORTED(); |
| 28 | |
| 29 | uint64_t ls64_input_buffer[LS64_ARRAYSIZE] = {1, 2, 3, 4, 5, 6, 7, 8}; |
| 30 | uint64_t ls64_output_buffer[LS64_ARRAYSIZE] = {0}; |
| 31 | /* |
| 32 | * Address where the data will be written to/read from with instructions |
| 33 | * st64b and ld64b respectively. |
| 34 | * Can only be in range (0x1d000000 - 0x1d00ffff) and be 64-byte aligned. |
| 35 | */ |
| 36 | uint64_t *store_address = (uint64_t *)LS64_ATOMIC_DEVICE_BASE; |
| 37 | |
| 38 | /** |
| 39 | * FEAT_LS64 : Execute LD64B and ST64B Instructions. |
| 40 | * This test copies data from input buffer, an array of 8-64bit |
| 41 | * unsigned integers to an output buffer via LD64B and ST64B |
| 42 | * atomic operation instructions. |
| 43 | * |
| 44 | * NOTE: As we cannot pre-write into LS64_ATOMIC_DEVICE_BASE memory |
| 45 | * via other instructions, we first load the data from a normal |
| 46 | * input buffer into the consecutive registers and then copy them in one |
| 47 | * atomic operation via st64b to Device memory(LS64_ATOMIC_DEVICE_BASE). |
| 48 | * Further we load the data from the same device memory into a normal |
| 49 | * output buffer through general registers and verify the buffers to |
| 50 | * ensure instructions copied the data as per the architecture. |
| 51 | */ |
| 52 | |
| 53 | ls64_store(ls64_input_buffer, store_address); |
| 54 | ls64_load(store_address, ls64_output_buffer); |
| 55 | |
| 56 | for (uint8_t i = 0U; i < LS64_ARRAYSIZE; i++) { |
Boyan Karatotev | 8f17515 | 2025-06-23 16:18:03 +0100 | [diff] [blame^] | 57 | VERBOSE("Input Buffer[%d]=%lld\n", i, ls64_input_buffer[i]); |
| 58 | VERBOSE("Output Buffer[%d]=%lld\n", i, ls64_output_buffer[i]); |
Jayanth Dodderi Chidanand | cd6c94b | 2022-02-15 17:19:05 +0000 | [diff] [blame] | 59 | |
| 60 | if (ls64_input_buffer[i] != ls64_output_buffer[i]) { |
| 61 | return TEST_RESULT_FAIL; |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | return TEST_RESULT_SUCCESS; |
| 66 | #else |
Jayanth Dodderi Chidanand | cd6c94b | 2022-02-15 17:19:05 +0000 | [diff] [blame] | 67 | SKIP_TEST_IF_AARCH32(); |
| 68 | #endif /* __aarch64_ */ |
| 69 | #else |
| 70 | tftf_testcase_printf("Test supported only on FVP \n"); |
| 71 | return TEST_RESULT_SKIPPED; |
| 72 | #endif /* PLAT_fvp */ |
| 73 | |
| 74 | } |
Andre Przywara | 72b7ce1 | 2024-11-04 13:44:39 +0000 | [diff] [blame] | 75 | |
| 76 | /* |
| 77 | * @brief Test LS64_ACCDATA feature support when the extension is enabled. |
| 78 | * |
| 79 | * Write to the ACCDATA_EL1 system register, and read it back. This is |
| 80 | * primarily to see if accesses to this register trap to EL3 (they should not). |
| 81 | * |
| 82 | * @return test_result_t |
| 83 | */ |
| 84 | test_result_t test_ls64_accdata_sysreg(void) |
| 85 | { |
| 86 | #ifdef __aarch64__ |
| 87 | SKIP_TEST_IF_LS64_ACCDATA_NOT_SUPPORTED(); |
| 88 | |
| 89 | write_sys_accdata_el1(0x1234567890); |
| 90 | if ((read_sys_accdata_el1() & 0xffffffff) != 0x34567890) { |
| 91 | NOTICE("SYS_ACCDATA_EL1: 0x%lx\n", read_sys_accdata_el1()); |
| 92 | return TEST_RESULT_FAIL; |
| 93 | } |
| 94 | |
| 95 | return TEST_RESULT_SUCCESS; |
| 96 | #else |
| 97 | SKIP_TEST_IF_AARCH32(); |
| 98 | #endif /* __aarch64_ */ |
| 99 | } |