diff options
Diffstat (limited to 'framework')
-rw-r--r-- | framework/aarch64/asm_helpers.S | 93 | ||||
-rw-r--r-- | framework/aarch64/entrypoint.S | 4 | ||||
-rw-r--r-- | framework/aarch64/tftf_asm_macros.S | 89 | ||||
-rw-r--r-- | framework/delay.c | 49 | ||||
-rw-r--r-- | framework/framework.mk | 64 | ||||
-rw-r--r-- | framework/helpers.c | 330 | ||||
-rw-r--r-- | framework/include/irq.h | 58 | ||||
-rw-r--r-- | framework/include/suspend.h | 38 | ||||
-rw-r--r-- | framework/include/tests_api.h | 175 | ||||
-rw-r--r-- | framework/include/tftf.h | 22 | ||||
-rw-r--r-- | framework/irq.c | 199 | ||||
-rw-r--r-- | framework/main.c | 3 | ||||
-rw-r--r-- | framework/nvm_results_helpers.c | 281 | ||||
-rw-r--r-- | framework/platform.c | 47 | ||||
-rw-r--r-- | framework/psci.c | 59 | ||||
-rw-r--r-- | framework/smc.c | 56 | ||||
-rw-r--r-- | framework/systimer.c | 141 | ||||
-rw-r--r-- | framework/trusted_os.c | 57 |
18 files changed, 322 insertions, 1443 deletions
diff --git a/framework/aarch64/asm_helpers.S b/framework/aarch64/asm_helpers.S deleted file mode 100644 index a50d5ee..0000000 --- a/framework/aarch64/asm_helpers.S +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <tftf_asm_macros.S> - - .globl asm_tftf_smc64 -#if SUPPORT_VFP - .globl disable_fp_traps -#endif - - .section .text, "ax" - -/* ----------------------------------------------------------------------- - * __noinline smc64_ret_values asm_tftf_smc64(uint64_t arg0, - * uint64_t arg1, - * uint64_t arg2, - * uint64_t arg3, - * uint64_t arg4, - * uint64_t arg5, - * uint64_t arg6); - * ----------------------------------------------------------------------- - */ -.type asm_tftf_smc64 STT_FUNC -asm_tftf_smc64: - /* - * According to the AAPCS64, x8 is the indirect result location - * register. It contains the address of the memory block that the caller - * has reserved to hold the result, i.e. the smc64_ret_values structure - * in our case. - * x8 might be clobbered across the SMC call so save it on the stack. - */ - str x8, [sp, #-8]! - - /* SMC arguments are already stored in x0-x6 */ - smc #0 - - /* Pop x8 into a caller-saved register */ - ldr x9, [sp], #8 - - /* - * Return values are stored in x0-x3, put them in the 'smc64_ret_values' - * return structure - */ - stp x0, x1, [x9, #0] - stp x2, x3, [x9, #16] - ret - -#if SUPPORT_VFP -disable_fp_traps: - JUMP_EL1_OR_EL2 x0, _disable_fp_traps_el1, _disable_fp_traps_el2 -_disable_fp_traps_el1: - mrs x0, cpacr_el1 // Read EL1 Coprocessor Access Control Register (CPACR) - orr x0, x0, #CPACR_EL1_FPEN(3) // Disable trapping of instructions accessing FP regs - msr cpacr_el1, x0 // Write back EL1 Coprocessor Access Control Register (CPACR) - ret -_disable_fp_traps_el2: - mrs x0, cptr_el2 - mov x1, #TFP_BIT - bic x0, x0, x1 - msr cptr_el2, x0 - ret - -#endif - -dead: - b dead diff --git a/framework/aarch64/entrypoint.S b/framework/aarch64/entrypoint.S index 33eae29..6cf7445 100644 --- a/framework/aarch64/entrypoint.S +++ b/framework/aarch64/entrypoint.S @@ -11,8 +11,8 @@ */ #include <arch.h> +#include <asm_macros.S> #include <tftf.h> -#include <tftf_asm_macros.S> .globl tftf_entrypoint .globl tftf_hotplug_entry @@ -118,7 +118,7 @@ tftf_hotplug_entry: * Enable the MMU * -------------------------------------------------------------------- */ - bl tftf_enable_mmu + bl tftf_plat_enable_mmu /* -------------------------------------------------------------------- * Give ourselves a stack in normal memory. diff --git a/framework/aarch64/tftf_asm_macros.S b/framework/aarch64/tftf_asm_macros.S deleted file mode 100644 index 08baf26..0000000 --- a/framework/aarch64/tftf_asm_macros.S +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <arch.h> - - .macro asm_read_sysreg_el1_or_el2 sysreg - mrs x0, CurrentEL - cmp x0, #(MODE_EL1 << MODE_EL_SHIFT) - b.eq 1f - cmp x0, #(MODE_EL2 << MODE_EL_SHIFT) - b.eq 2f - b dead -1: - mrs x0, \sysreg\()_el1 - b 3f -2: - mrs x0, \sysreg\()_el1 -3: - .endm - - .macro asm_write_sysreg_el1_or_el2 sysreg scratch_reg - mrs \scratch_reg, CurrentEL - cmp \scratch_reg, #(MODE_EL1 << MODE_EL_SHIFT) - b.eq 1f - cmp \scratch_reg, #(MODE_EL2 << MODE_EL_SHIFT) - b.eq 2f - b dead -1: - msr \sysreg\()_el1, x0 - b 3f -2: - msr \sysreg\()_el2, x0 -3: - .endm - - .macro asm_read_sctlr_el1_or_el2 - asm_read_sysreg_el1_or_el2 sctlr - .endm - - .macro asm_write_sctlr_el1_or_el2 scratch_reg - asm_write_sysreg_el1_or_el2 sctlr \scratch_reg - .endm - - .macro asm_write_vbar_el1_or_el2 scratch_reg - asm_write_sysreg_el1_or_el2 vbar \scratch_reg - .endm - -/* - * Depending on the current exception level, jump to 'label_el1' or 'label_el2'. - * If the current exception level is neither EL1 nor EL2, jump to an infinite - * loop instead. - * Provide the macro with a scratch 64-bit register to use, its contents prior - * to calling this function will be lost. - */ - .macro JUMP_EL1_OR_EL2 scratch_reg, label_el1, label_el2 - mrs \scratch_reg, CurrentEL - cmp \scratch_reg, #(MODE_EL1 << MODE_EL_SHIFT) - b.eq \label_el1 - cmp \scratch_reg, #(MODE_EL2 << MODE_EL_SHIFT) - b.eq \label_el2 - b dead - .endm diff --git a/framework/delay.c b/framework/delay.c deleted file mode 100644 index 055581c..0000000 --- a/framework/delay.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <arch_helpers.h> -#include <tftf.h> - -void waitms(uint64_t waitms) -{ - uint64_t cntp_ct_val_base; - uint32_t cnt_frq; - uint32_t wait_cycles; - - cnt_frq = read_cntfrq_el0(); - cntp_ct_val_base = read_cntpct_el0(); - - /* Waitms in terms of counter freq */ - wait_cycles = (waitms * cnt_frq) / 1000; - - while (read_cntpct_el0() - cntp_ct_val_base < wait_cycles) - ; - -} diff --git a/framework/framework.mk b/framework/framework.mk index ab8d777..402ba43 100644 --- a/framework/framework.mk +++ b/framework/framework.mk @@ -30,40 +30,40 @@ AUTOGEN_DIR := $(BUILD_PLAT)/autogen -FRAMEWORK_INCLUDES := -Iframework/aarch64 \ - -Iframework/include \ +FRAMEWORK_INCLUDES := -Iframework/include \ + -Iinclude/common \ -I${AUTOGEN_DIR} -FRAMEWORK_SOURCES := ${AUTOGEN_DIR}/tests_list.c \ - framework/aarch64/arch.c \ - framework/aarch64/asm_helpers.S \ - framework/aarch64/asm_platform_weak.S \ - framework/aarch64/entrypoint.S \ - framework/aarch64/exceptions.S \ - framework/debug.c \ - framework/delay.c \ - framework/helpers.c \ - framework/irq.c \ - framework/main.c \ - framework/platform.c \ - framework/psci.c \ - framework/report.c \ - framework/smc.c \ - framework/systimer.c \ - framework/trusted_os.c \ - lib/aarch64/cache_helpers.S \ - lib/aarch64/misc_helpers.S \ - lib/aarch64/xlat_helpers.c \ - lib/aarch64/xlat_tables.c \ - lib/locks/exclusive/spinlock.S \ - lib/power_management/hotplug/hotplug.c \ - lib/stdlib/std.c \ - lib/suspend/tftf_suspend.c \ - lib/suspend/asm_tftf_suspend.S \ - lib/utils/uuid.c \ - plat/common/aarch64/plat_common.c \ - plat/common/aarch64/platform_helpers.S \ - plat/common/aarch64/platform_mp_stack.S \ +FRAMEWORK_SOURCES := ${AUTOGEN_DIR}/tests_list.c \ + framework/aarch64/arch.c \ + framework/aarch64/asm_platform_weak.S \ + framework/aarch64/entrypoint.S \ + framework/aarch64/exceptions.S \ + framework/debug.c \ + framework/main.c \ + framework/nvm_results_helpers.c \ + framework/report.c \ + lib/aarch64/cache_helpers.S \ + lib/aarch64/misc_helpers.S \ + lib/aarch64/xlat_helpers.c \ + lib/aarch64/xlat_tables.c \ + lib/delay/delay.c \ + lib/irq/irq.c \ + lib/locks/spinlock.S \ + lib/power_management/hotplug/hotplug.c \ + lib/power_management/suspend/asm_tftf_suspend.S \ + lib/power_management/suspend/tftf_suspend.c \ + lib/psci/psci.c \ + lib/smc/asm_smc.S \ + lib/smc/smc.c \ + lib/stdlib/std.c \ + lib/systimer/systimer.c \ + lib/trusted_os/trusted_os.c \ + lib/utils/mp_printf.c \ + lib/utils/uuid.c \ + plat/common/aarch64/plat_common.c \ + plat/common/aarch64/platform_helpers.S \ + plat/common/aarch64/platform_mp_stack.S \ plat/common/tftf_nvm_accessors.c TFTF_LINKERFILE := framework/tftf.ld.S diff --git a/framework/helpers.c b/framework/helpers.c deleted file mode 100644 index e3daf24..0000000 --- a/framework/helpers.c +++ /dev/null @@ -1,330 +0,0 @@ -/** @file -* -* Copyright (c) 2013, ARM Limited. All rights reserved. -* -* This program and the accompanying materials -* are licensed and made available under the terms and conditions of the BSD License -* which accompanies this distribution. The full text of the license may be found at -* http://opensource.org/licenses/bsd-license.php -* -* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -* -**/ - -#include <arm_gic.h> -#include <string.h> -#include <assert.h> -#include <stdarg.h> -#include <stdio.h> - -#include <arch_helpers.h> -#include <platform.h> -#include <tftf.h> -#include <xlat_tables.h> -#include <spinlock.h> -#include <debug.h> -#include <psci.h> -#include <nvm.h> - -extern unsigned long __COHERENT_RAM_START__; -extern unsigned long __COHERENT_RAM_END__; - -/* - * The next 2 constants identify the extents of the coherent memory region. - * These addresses are used by the MMU setup code and therefore they must be - * page-aligned. It is the responsibility of the linker script to ensure that - * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols - * refer to page-aligned addresses. - */ -#define COH_START (unsigned long)(&__COHERENT_RAM_START__) -#define COH_LIMIT (unsigned long)(&__COHERENT_RAM_END__) - -/* Lock to avoid concurrent accesses to the serial console */ -static spinlock_t printf_lock; - -static const TEST_NVM nvm_init_state = { - TESTS_MAGIC_VALUE, // magic - NULL, // current_testcase - NULL, // next_testcase - { 0 }, // testcase_buffer - { { // testcase_results - TEST_NOT_RUN, /* testcase_results.result */ - 0, // testcase_results.duration - 0, // testcase_results.output_offset - 0, // testcase_results.output_size - } }, - 0, // result_buffer_size - NULL, // result_buffer -}; - -STATUS tftf_init_nvm(void) { - STATUS status; - unsigned magic; - - // Check if NVM needs to be initialized. - // NVM needs to be initialized when the magic number stored in NVM doesn't - // have the expected value. - // Note: this method isn't perfect and will sometimes lead to false results: - // NVM could be uninitialised but happen to have the expected magic value, - // which will make TFTF think it is already initialised. But we'll consider - // that's good enough. - status = tftf_nvm_read(TEST_NVM_MAGIC_OFFSET, &magic, sizeof(unsigned)); - if (status != STATUS_SUCCESS) { - return status; - } - - if (magic != TESTS_MAGIC_VALUE) { - status = tftf_nvm_write(0, &nvm_init_state, sizeof(nvm_init_state)); - if (status != STATUS_SUCCESS) { - return status; - } - } - - return STATUS_SUCCESS; -} - -STATUS tftf_clean_nvm(void) { - unsigned magic = 0xDEADC0DE; - - // Invalidate magic number. - // This will cause TFTF to re-initialise its data structures next time it runs. - return tftf_nvm_write(TEST_NVM_MAGIC_OFFSET, &magic, sizeof(unsigned)); -} - -void tftf_set_current_testcase(TESTCASE_FUNC testcase_function) { - tftf_nvm_write(TEST_NVM_CURRENT_TESTCASE_OFFSET, &testcase_function, sizeof(TESTCASE_FUNC)); -} - -STATUS tftf_get_current_testcase(TESTCASE_FUNC* testcase_function) { - return tftf_nvm_read(TEST_NVM_CURRENT_TESTCASE_OFFSET, testcase_function, sizeof(TESTCASE_FUNC)); -} - -void tftf_set_next_testcase(TESTCASE_FUNC testcase_function) { - tftf_nvm_write(TEST_NVM_NEXT_TESTCASE_OFFSET, &testcase_function, sizeof(TESTCASE_FUNC)); -} - -STATUS tftf_get_next_testcase(TESTCASE_FUNC* testcase_function) { - return tftf_nvm_read(TEST_NVM_NEXT_TESTCASE_OFFSET, testcase_function, sizeof(TESTCASE_FUNC)); -} - -STATUS tftf_testcase_set_result(const TESTCASE* testcase, TEST_RESULT result, const char* output, - unsigned long long duration) -{ - STATUS status; - unsigned result_buffer_size = 0; - TESTCASE_RESULT test_result; - - assert(testcase != NULL); - - // Initialize Test case result. - test_result.result = result; - test_result.duration = duration; - test_result.output_offset = 0; - test_result.output_size = output ? strlen(output) : 0; - - // Does the test have an output? - if (test_result.output_size != 0) { - // Get the size of the buffer containing all tests outputs. - status = tftf_nvm_read(TEST_NVM_RESULT_BUFFER_SIZE_OFFSET, &result_buffer_size, sizeof(unsigned)); - if (status != STATUS_SUCCESS) { - return status; - } - - // Write the output buffer at the end of the string buffer in NVM. - test_result.output_offset = result_buffer_size; - status = tftf_nvm_write(TEST_NVM_RESULT_BUFFER_OFFSET + result_buffer_size, - output, test_result.output_size + 1); - if (status != STATUS_SUCCESS) { - return status; - } - - // And update the buffer size into NVM - result_buffer_size += test_result.output_size + 1; - status = tftf_nvm_write(TEST_NVM_RESULT_BUFFER_SIZE_OFFSET, - &result_buffer_size, sizeof(unsigned)); - if (status != STATUS_SUCCESS) { - return status; - } - } - - // Write the test result into NVM. - return tftf_nvm_write(TEST_NVM_TESTCASE_RESULTS_OFFSET + (testcase->index * sizeof(TESTCASE_RESULT)), - &test_result, sizeof(TESTCASE_RESULT)); -} - -STATUS tftf_testcase_update_result(const TESTCASE* testcase, TEST_RESULT result) { - STATUS status; - TESTCASE_RESULT test_result; - - // Read the test result from NVM - status = tftf_nvm_read(TEST_NVM_TESTCASE_RESULTS_OFFSET + (testcase->index * sizeof(TESTCASE_RESULT)), - &test_result, sizeof(TESTCASE_RESULT)); - if (status != STATUS_SUCCESS) { - return status; - } - - // Update Test case result - test_result.result = result; - - // Write back the test result into NVM - return tftf_nvm_write(TEST_NVM_TESTCASE_RESULTS_OFFSET + (testcase->index * sizeof(TESTCASE_RESULT)), - &test_result, sizeof(TESTCASE_RESULT)); -} - -STATUS tftf_testcase_get_result(const TESTCASE* testcase, TESTCASE_RESULT *result, - char *test_output) { - STATUS status; - unsigned output_size; - - assert(testcase != NULL); - assert(result != NULL); - assert(test_output != NULL); - - status = tftf_nvm_read(TEST_NVM_TESTCASE_RESULTS_OFFSET + (testcase->index * sizeof(TESTCASE_RESULT)), - result, sizeof(TESTCASE_RESULT)); - if (status != STATUS_SUCCESS) { - return status; - } - - output_size = result->output_size; - - if (output_size != 0) { - status = tftf_nvm_read(TEST_NVM_RESULT_BUFFER_OFFSET + result->output_offset, - test_output, output_size); - if (status != STATUS_SUCCESS) { - return status; - } - } - - test_output[output_size] = 0; - - return STATUS_SUCCESS; -} - -STATUS tftf_get_testcase_index(TESTCASE_FUNC testcase_function, unsigned *testsuite_index, unsigned *testcase_index, - unsigned get_next) -{ - unsigned i, j; - - if (!testcase_function || !testsuite_index || !testcase_index) { - return STATUS_INVALID_PARAMETER; - } - - for (i = 0; testsuites[i].name != NULL; i++) { - for (j = 0; testsuites[i].testcases[j].name != NULL; j++) { - if (testcase_function == testsuites[i].testcases[j].test) { - // Find the next testcase - if (get_next) { - if (testsuites[i].testcases[j+1].name != NULL) { - *testsuite_index = i; - *testcase_index = j+1; - } else if (testsuites[i+1].testcases != NULL) { - *testsuite_index = i+1; - *testcase_index = 0; - } else { - return STATUS_NOT_FOUND; - } - } else { - *testsuite_index = i; - *testcase_index = j; - } - return STATUS_SUCCESS; - } - } - } - return STATUS_NOT_FOUND; -} - -STATUS test_set_passed_and_next(TESTCASE_FUNC testcase_function) { - STATUS status; - unsigned testsuite_index, testcase_index; - unsigned next_testsuite_index, next_testcase_index; - - status = tftf_get_testcase_index(testcase_function, &testsuite_index, &testcase_index, 0); - if (status != STATUS_SUCCESS) { - return status; - } - status = tftf_get_testcase_index(testcase_function, &next_testsuite_index, &next_testcase_index, 1); - if (status != STATUS_SUCCESS) { - return status; - } - - // Set the NVM to resume the test execution - tftf_set_next_testcase(testsuites[next_testsuite_index].testcases[next_testcase_index].test); - tftf_set_current_testcase(NULL); - - // Assume the test has passed - if it fails then we will overwrite the result - return tftf_testcase_set_result(&testsuites[testsuite_index].testcases[testcase_index], - TEST_RESULT_SUCCESS, NULL, 0); -} - -STATUS tftf_testcase_set_result_as_crashed(TESTCASE_FUNC crashed_testcase_function) { - STATUS status; - unsigned testsuite_index, testcase_index; - - status = tftf_get_testcase_index(crashed_testcase_function, &testsuite_index, &testcase_index, 0); - if (status != STATUS_SUCCESS) { - return status; - } - - return tftf_testcase_update_result(&testsuites[testsuite_index].testcases[testcase_index], TEST_RESULT_CRASHED); -} - - -void mp_printf(const char *fmt, ...) -{ - va_list ap; - char str[256]; - - /* - * TODO: It would be simpler to use vprintf() instead of - * vsnprintf() + printf(), we wouldn't need to declare a static buffer - * for storing the product of vsnprintf(). Unfortunately our C library - * doesn't provide vprintf() at the moment. - * Import vprintf() code from FreeBSD C library to our local C library. - */ - va_start(ap, fmt); - vsnprintf(str, sizeof(str), fmt, ap); - str[sizeof(str) - 1] = 0; - va_end(ap); - - spin_lock(&printf_lock); - printf("[cpu 0x%.4x] ", read_mpidr() & 0xFFFF); - printf("%s", str); - spin_unlock(&printf_lock); -} - -bool tftf_is_core_enabled(unsigned int core_pos) -{ - smc64_ret_values core_state; - smc64_args aff_info_args = { - PSCI_AFFINITY_INFO_AARCH64, - tftf_platform_core_pos_to_mpid(core_pos), - 0 /* affinity level */ - }; - - core_state = tftf_smc64(&aff_info_args); - - return core_state.ret0 == PSCI_STATE_ON; -} - -void tftf_configure_mmu(void) -{ - mmap_add_region(COH_START, COH_START, COH_LIMIT - COH_START, - MT_DEVICE | MT_RW | MT_NS); - mmap_add(tftf_platform_get_mmap()); - init_xlat_tables(); - - tftf_enable_mmu(); -} - -void tftf_enable_mmu(void) -{ - if (IS_IN_EL1()) - enable_mmu_el1(0); - else if (IS_IN_EL2()) - enable_mmu_el2(0); - else - panic(); -} diff --git a/framework/include/irq.h b/framework/include/irq.h deleted file mode 100644 index 181358d..0000000 --- a/framework/include/irq.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __IRQ_H__ -#define __IRQ_H__ - -#include <platform.h> -#include <platform_def.h> /* For CACHE_WRITEBACK_GRANULE */ - -#ifndef __ASSEMBLY__ - -#include <tests_api.h> /* for irq_handler type */ - -typedef struct { - unsigned int num; - irq_handler handler; -} irq_desc; -typedef irq_desc spi_desc; - -typedef union { - irq_desc desc; - unsigned char align[CACHE_WRITEBACK_GRANULE]; -} ppi_desc; -typedef ppi_desc sgi_desc; - -void tftf_irq_setup(void); -int tftf_irq_handler(void); - -#endif /* __ASSEMBLY__ */ - -#endif /* __IRQ_H__ */ diff --git a/framework/include/suspend.h b/framework/include/suspend.h deleted file mode 100644 index 18bb8b0..0000000 --- a/framework/include/suspend.h +++ /dev/null @@ -1,38 +0,0 @@ -/** @file -* -* Copyright (c) 2014, ARM Limited. All rights reserved. -* -* This program and the accompanying materials -* are licensed and made available under the terms and conditions of the BSD License -* which accompanies this distribution. The full text of the license may be found at -* http://opensource.org/licenses/bsd-license.php -* -* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -* -**/ - -#ifndef __SUSPEND_H__ -#define __SUSPEND_H__ - -#include <stdint.h> - -/* - * It is an Api used to enter a suspend state. It does the following: - * - Allocates space for saving architectural and non-architectural CPU state on - * stack - * - Saves architecture state of the CPU in the space allocated which consists: - * a. Callee registers - * b. System control registers. ex: MMU, SCTLR_EL1 - * - Sets context ID to the base of the stack allocated for saving context - * - Calls Secure Platform Firmware to enter suspend - * - If suspend fails, It restores the callee registers - * power state: PSCI power state to be sent via SMC - * Returns: PSCI_E_SUCCESS or PSCI_E_INVALID_PARAMS - * - * Note: This api might not test all use cases, as the context ID and resume - * entrypoint is in the control of the framework. - */ -unsigned int tftf_cpu_suspend(uint32_t power_state); - -#endif /* __SUSPEND_H__ */ diff --git a/framework/include/tests_api.h b/framework/include/tests_api.h deleted file mode 100644 index fe3c292..0000000 --- a/framework/include/tests_api.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/***************************************************************************** - * This header file lists and documents all functions that a test function - * may use. - ****************************************************************************/ - -#ifndef __TESTS_API_H__ -#define __TESTS_API_H__ - -#ifndef __ASSEMBLY__ - -#include <stdint.h> -#include <tftf_common.h> - -/* Number of iterations for repetitive tests */ -#define TFTF_LOOPS 1000 - -/* - * Print a formatted string on the UART. - * - * Does the same thing as the standard libc's printf() function but in a MP-safe - * manner, i.e. it can be called from several CPUs simultaneously without - * getting interleaved messages. - * - * The messages printed using mp_printf() won't be saved in the test results - * (use tftf_testcase_output() instead for that). mp_printf() is meant to be - * used for debug traces only. Unlike messages stored in the tests output which - * appear only at the end of the test session in the test report, messages - * printed using mp_printf() will be displayed straight away. - * - * Messaged will be prefixed by the CPU MPID issuing the call, like that: - * [cpu 0x0002] Sending SGI #1 to cpu 0 - */ -__attribute__((format(printf, 1, 2))) -void mp_printf(const char *fmt, ...); - -typedef int (*irq_handler)(void *data); - -/* - * Register an interrupt handler for a given interrupt number - */ -int tftf_irq_register(unsigned int num, irq_handler dev_irq_handler); - -/* - * Program the timer to fire in 'time_ms' milliseconds - */ -void tftf_systimer_fire_in(uint64_t time_ms); - -/* Register an SGI for waking up the core from the lead CPU */ -void tftf_register_sgi_wake_interrupt(unsigned int core_pos); - -/* Handler for the SGI wakeup interrupt */ -int tftf_sgi_generic_wake_handler(void *data); - -/* Handler for systimer */ -int tftf_systimer_handler(void *data); - -/* Data associated with the reception of an SGI */ -typedef struct { - /* Interrupt ID of the signaled interrupt */ - unsigned int irq_id; - /* Identifies the processor that requested the SGI */ - unsigned int cpu_id; -} sgi_data; - -/* - * Send an SGI (Software Generated Interrupt) to a given core. - */ -void tftf_send_sgi(unsigned int sgi_id, unsigned int core_pos); - -/* - * Possible error codes for signaling the result of a test - */ -typedef enum { - /* - * Values used internally by the framework. Not to be used by test - * cases. - */ - TEST_NOT_RUN, - TEST_STARTING, - /* - * Values that a test case can return to report its result - */ - TEST_RESULT_SKIPPED, - TEST_RESULT_SUCCESS, - TEST_RESULT_FAIL, - TEST_RESULT_CRASHED, -} TEST_RESULT; - -/* - * Prototype of a task function pointer - */ -typedef TEST_RESULT (*TFTF_TASK)(unsigned core_pos, void *argument); - -void tftf_hotplug_entry(void); - -bool tftf_is_core_enabled(unsigned int core_pos); - -/* - * PSCI Function Wrappers - * - * Smc calls to PSCI functions - */ -uint32_t tftf_psci_cpu_on(uint64_t target_cpu, - uint64_t entry_point_address, - uint64_t context_id); -uint32_t tftf_psci_cpu_off(void); - -void waitms(uint64_t ms); - -bool tftf_core_participates_in_testcase(unsigned core_pos, - unsigned testcase_index); - -/* - * Write a string in the test output buffer. - * The string will appear in the test report. - */ -void tftf_testcase_output(const char *string); - -/* SMC64 calls can take up to 7 64-bit arguments */ -typedef struct { - uint64_t arg0; - uint64_t arg1; - uint64_t arg2; - uint64_t arg3; - uint64_t arg4; - uint64_t arg5; - uint64_t arg6; -} smc64_args; - -/* SMC64 calls can return up to 4 64-bit arguments */ -typedef struct { - uint64_t ret0; - uint64_t ret1; - uint64_t ret2; - uint64_t ret3; -} smc64_ret_values; - -/* - * Trigger an SMC64 call. - */ -smc64_ret_values tftf_smc64(const smc64_args *args); - -#endif /* __ASSEMBLY__ */ - -#endif /* __TESTS_API_H__ */ diff --git a/framework/include/tftf.h b/framework/include/tftf.h index 02e6346..b423528 100644 --- a/framework/include/tftf.h +++ b/framework/include/tftf.h @@ -16,9 +16,9 @@ #define __TFTF_H__ #ifndef __ASSEMBLY__ +#include <status.h> #include <stddef.h> -#include <tests_api.h> -#include <tftf_common.h> +#include <tftf_lib.h> #define TFTF_WELCOME_STR "Booting trusted firmware test framework" @@ -29,6 +29,7 @@ #define TEST_REPORT_FORMAT_RAW 0 #define TEST_REPORT_FORMAT_JUNIT 1 +typedef unsigned TEST_REPORT_FORMAT; extern const char build_message[]; @@ -66,13 +67,6 @@ typedef struct { const TESTCASE *testcases; } TEST_SUITE; -/** -** @brief Write a string in the test output buffer. -** -** @note The test output buffer we are talking about here is a temporary buffer -** stored in RAM. This function doesn't write anything into NVM. -*/ -void tftf_testcase_output(const char* string); // The definition of this global variable is generated by the script 'tftf_generate_test_list' // during the build process @@ -109,8 +103,6 @@ STATUS tftf_testcase_set_result(const TESTCASE* testcase, TEST_RESULT result, co STATUS tftf_testcase_get_result(const TESTCASE* testcase, TESTCASE_RESULT *result, char *test_output); STATUS tftf_testcase_update_result(const TESTCASE* testcase, TEST_RESULT result); -typedef unsigned TEST_REPORT_FORMAT; - void tftf_report_generate(void); /* @@ -145,12 +137,8 @@ int tftf_systimer_setup(void); */ void __dead2 run_tests(void); -/* - * Prevent the compiler from optimising the access to a variable. - * Note that this only affects the compiler, this is NOT a run-time - * memory barrier. - */ -#define ACCESS(var) (*(volatile __typeof__(var) *)&(var)) +/* Entry point for a CPU that has just been powered up */ +void tftf_hotplug_entry(void); #endif /*__ASSEMBLY__*/ diff --git a/framework/irq.c b/framework/irq.c deleted file mode 100644 index a5ad679..0000000 --- a/framework/irq.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <arch_helpers.h> -#include <arm_gic.h> -#include <assert.h> -#include <gic_v2.h> -#include <irq.h> -#include <platform.h> -#include <platform_def.h> -#include <string.h> -#include <tftf.h> - -#define GIC_CPU_INVALID_ID 0xFF - -static uint8_t gic_cpu_ids[GIC_MAX_CPU_INTERFACES] = {GIC_CPU_INVALID_ID, - GIC_CPU_INVALID_ID, - GIC_CPU_INVALID_ID, - GIC_CPU_INVALID_ID, - GIC_CPU_INVALID_ID, - GIC_CPU_INVALID_ID, - GIC_CPU_INVALID_ID, - GIC_CPU_INVALID_ID}; -static spi_desc spi_desc_table[PLAT_MAX_SPI_ID]; -static ppi_desc ppi_desc_table[PLATFORM_CORE_COUNT][MAX_PPI_ID + 1]; -static sgi_desc sgi_desc_table[PLATFORM_CORE_COUNT][MAX_SGI_ID + 1]; - -void tftf_send_sgi(unsigned int sgi_id, unsigned int core_pos) -{ - uint32_t sgir_val; - unsigned int gic_cpu_id; - unsigned int target_mpid; - - assert(sgi_id <= MAX_SGI_ID); - -#if DEBUG - mp_printf("Sending SGI #%u to cpu %u\n", sgi_id, core_pos); -#endif - - target_mpid = tftf_platform_core_pos_to_mpid(core_pos); - gic_cpu_id = tftf_get_gic_cpu_id_from_mpidr(target_mpid); - - assert(gic_cpu_id != GIC_CPU_INVALID_ID); - sgir_val = sgi_id << GICD_SGIR_INTID_SHIFT; - sgir_val |= (1 << gic_cpu_id) << GICD_SGIR_CPUTL_SHIFT; - arm_gicd_write_sgir(sgir_val); -} - -int tftf_irq_register(unsigned int num, irq_handler dev_irq_handler) -{ - uint32_t linear_id; - uint32_t gic_cpu_id; - - /* Ensure we are dealing with what we can handle */ - assert(num <= PLAT_MAX_SPI_ID + MAX_PPI_ID + 1); - - linear_id = platform_get_core_pos(read_mpidr()); - - /* Distinguish between SPIs, PPIs & SGIs */ - if (num > MAX_PPI_ID) { - /* TODO: We do not check for an existing handler */ - spi_desc_table[num].num = num; - spi_desc_table[num].handler = dev_irq_handler; - - /* - * Instruct the GIC Distributor to forward the interrupt to - * the current core - */ - gic_cpu_id = tftf_get_gic_cpu_id_from_mpidr(read_mpidr()); - arm_gicd_set_itargetsr(num, gic_cpu_id); - } else { - if (num > MAX_SGI_ID) { - ppi_desc_table[linear_id][num].desc.num = num; - ppi_desc_table[linear_id][num].desc.handler = - dev_irq_handler; - } else { - sgi_desc_table[linear_id][num].desc.num = num; - sgi_desc_table[linear_id][num].desc.handler = - dev_irq_handler; - } - } - - /* Configure the interrupt */ - arm_gicd_set_ipriorityr(num, GIC_HIGHEST_NS_PRIORITY); - arm_gicd_set_isenabler(num); - - return 0; -} - -int tftf_irq_handler(void) -{ - unsigned int val, irq, gic_cpu_id, linear_id; - int rc = 0; - sgi_data data; - - /* Acknowledge the interrupt */ - val = arm_gicc_read_iar(); - irq = get_gicc_iar_intid(val); - - /* Ensure we are dealing with what we can handle */ - assert(irq <= PLAT_MAX_SPI_ID + MAX_PPI_ID + 1); - - /* Distinguish between SPIs, PPIs & SGIs */ - if (irq > MAX_PPI_ID) { - assert(spi_desc_table[irq].num == irq); - rc = spi_desc_table[irq].handler(&irq); - } else { - linear_id = platform_get_core_pos(read_mpidr()); - if (irq > MAX_SGI_ID) { - assert(ppi_desc_table[linear_id][irq].desc.num == irq); - rc = ppi_desc_table[linear_id][irq].desc.handler(&irq); - } else { - gic_cpu_id = get_gicc_iar_cpuid(val); - data.irq_id = irq; - data.cpu_id = tftf_get_cpu_id_from_gic_id(gic_cpu_id); - assert(sgi_desc_table[linear_id][irq].desc.num == irq); - rc = sgi_desc_table[linear_id][irq].desc.handler(&data); - } - } - - /* Deactivate the interrupt */ - arm_gicc_write_eoir(val); - - return rc; -} - -void tftf_irq_setup(void) -{ - memset(spi_desc_table, 0, sizeof(spi_desc_table)); - memset(ppi_desc_table, 0, sizeof(ppi_desc_table)); - memset(sgi_desc_table, 0, sizeof(sgi_desc_table)); -} - -void tftf_register_gic_id(void) -{ - int linear_id = platform_get_core_pos(read_mpidr()); - uint8_t gicd_itarget_val; - - gicd_itarget_val = arm_gicd_get_itargetsr(0); - assert(gicd_itarget_val); - assert(linear_id < sizeof(gic_cpu_ids) / sizeof(gic_cpu_ids[0])); - gic_cpu_ids[linear_id] = __builtin_ctz(gicd_itarget_val); - dsb(); -} - -uint8_t tftf_get_gic_cpu_id_from_mpidr(unsigned long mpidr) -{ - unsigned int linear_id = platform_get_core_pos(mpidr); - assert(linear_id < sizeof(gic_cpu_ids) / sizeof(gic_cpu_ids[0])); - return gic_cpu_ids[linear_id]; -} - -uint8_t tftf_get_cpu_id_from_gic_id(uint8_t gic_id) -{ - assert(gic_id != GIC_CPU_INVALID_ID); - for (uint8_t i = 0; i < GIC_MAX_CPU_INTERFACES; i++) { - if (gic_cpu_ids[i] == gic_id) - return i; - } - /* assert if none of the cpus have the requested gic_id */ - assert(0); - return -1; -} - -int tftf_sgi_generic_wake_handler(void *data) -{ -#if DEBUG - mp_printf("Core 0x%x received SGI wake interrupt\n", - (unsigned int)read_mpidr()); -#endif - return 0; -} diff --git a/framework/main.c b/framework/main.c index ff0e4d7..9c43cdc 100644 --- a/framework/main.c +++ b/framework/main.c @@ -22,10 +22,11 @@ #include <platform_def.h> #include <power_management.h> #include <psci.h> +#include <sgi.h> #include <spinlock.h> #include <stdio.h> #include <string.h> -#include <tests_api.h> +#include <tftf_lib.h> #include <tftf.h> // Index of the current testsuite and the current testcase. diff --git a/framework/nvm_results_helpers.c b/framework/nvm_results_helpers.c new file mode 100644 index 0000000..dfa1822 --- /dev/null +++ b/framework/nvm_results_helpers.c @@ -0,0 +1,281 @@ +/** @file +* +* Copyright (c) 2013, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include <arch_helpers.h> +#include <assert.h> +#include <nvm.h> +#include <platform.h> +#include <string.h> + +static const TEST_NVM nvm_init_state = { + TESTS_MAGIC_VALUE, /* magic */ + NULL, /* current_testcase */ + NULL, /* next_testcase */ + { 0 }, /* testcase_buffer */ + { { /* testcase_results */ + TEST_NOT_RUN, /* testcase_results.result */ + 0, /* testcase_results.duration */ + 0, /* testcase_results.output_offset */ + 0, /* testcase_results.output_size */ + } }, + 0, /* result_buffer_size */ + NULL, /* result_buffer */ +}; + +STATUS tftf_init_nvm(void) +{ + STATUS status; + unsigned magic; + + /* + * Check if NVM needs to be initialized. + * NVM needs to be initialized when the magic number stored in NVM + * doesn't have the expected value. + * Note: this method isn't perfect and will sometimes lead to false + * results: NVM could be uninitialised but happen to have the expected + * magic value, which will make TFTF think it is already initialised. + * But we'll consider that's good enough. + */ + status = tftf_nvm_read(TEST_NVM_MAGIC_OFFSET, &magic, sizeof(unsigned)); + if (status != STATUS_SUCCESS) + return status; + + if (magic != TESTS_MAGIC_VALUE) { + status = tftf_nvm_write(0, &nvm_init_state, + sizeof(nvm_init_state)); + if (status != STATUS_SUCCESS) + return status; + } + + return STATUS_SUCCESS; +} + +STATUS tftf_clean_nvm(void) +{ + unsigned magic = 0xDEADC0DE; + + /* + * Invalidate magic number. + * This will cause TFTF to re-initialise its data structures next time + * it runs. + */ + return tftf_nvm_write(TEST_NVM_MAGIC_OFFSET, &magic, sizeof(unsigned)); +} + +void tftf_set_current_testcase(TESTCASE_FUNC testcase_function) +{ + tftf_nvm_write(TEST_NVM_CURRENT_TESTCASE_OFFSET, &testcase_function, sizeof(TESTCASE_FUNC)); +} + +STATUS tftf_get_current_testcase(TESTCASE_FUNC *testcase_function) +{ + return tftf_nvm_read(TEST_NVM_CURRENT_TESTCASE_OFFSET, testcase_function, sizeof(TESTCASE_FUNC)); +} + +void tftf_set_next_testcase(TESTCASE_FUNC testcase_function) +{ + tftf_nvm_write(TEST_NVM_NEXT_TESTCASE_OFFSET, &testcase_function, sizeof(TESTCASE_FUNC)); +} + +STATUS tftf_get_next_testcase(TESTCASE_FUNC *testcase_function) +{ + return tftf_nvm_read(TEST_NVM_NEXT_TESTCASE_OFFSET, testcase_function, sizeof(TESTCASE_FUNC)); +} + +STATUS tftf_testcase_set_result(const TESTCASE *testcase, + TEST_RESULT result, + const char *output, + unsigned long long duration) +{ + STATUS status; + unsigned result_buffer_size = 0; + TESTCASE_RESULT test_result; + + assert(testcase != NULL); + + /* Initialize Test case result */ + test_result.result = result; + test_result.duration = duration; + test_result.output_offset = 0; + test_result.output_size = output ? strlen(output) : 0; + + /* Does the test have an output? */ + if (test_result.output_size != 0) { + /* Get the size of the buffer containing all tests outputs */ + status = tftf_nvm_read(TEST_NVM_RESULT_BUFFER_SIZE_OFFSET, + &result_buffer_size, sizeof(unsigned)); + if (status != STATUS_SUCCESS) { + return status; + } + + /* + * Write the output buffer at the end of the string buffer in + * NVM + */ + test_result.output_offset = result_buffer_size; + status = tftf_nvm_write(TEST_NVM_RESULT_BUFFER_OFFSET + + result_buffer_size, + output, test_result.output_size + 1); + if (status != STATUS_SUCCESS) { + return status; + } + + /* And update the buffer size into NVM */ + result_buffer_size += test_result.output_size + 1; + status = tftf_nvm_write(TEST_NVM_RESULT_BUFFER_SIZE_OFFSET, + &result_buffer_size, sizeof(unsigned)); + if (status != STATUS_SUCCESS) + return status; + } + + /* Write the test result into NVM */ + return tftf_nvm_write(TEST_NVM_TESTCASE_RESULTS_OFFSET + + (testcase->index * sizeof(TESTCASE_RESULT)), + &test_result, sizeof(TESTCASE_RESULT)); +} + +STATUS tftf_testcase_update_result(const TESTCASE *testcase, TEST_RESULT result) +{ + STATUS status; + TESTCASE_RESULT test_result; + + /* Read the test result from NVM */ + status = tftf_nvm_read(TEST_NVM_TESTCASE_RESULTS_OFFSET + + (testcase->index * sizeof(TESTCASE_RESULT)), + &test_result, sizeof(TESTCASE_RESULT)); + if (status != STATUS_SUCCESS) { + return status; + } + + /* Update Test case result */ + test_result.result = result; + + /* Write back the test result into NVM */ + return tftf_nvm_write(TEST_NVM_TESTCASE_RESULTS_OFFSET + + (testcase->index * sizeof(TESTCASE_RESULT)), + &test_result, sizeof(TESTCASE_RESULT)); +} + +STATUS tftf_testcase_get_result(const TESTCASE *testcase, + TESTCASE_RESULT *result, + char *test_output) +{ + STATUS status; + unsigned output_size; + + assert(testcase != NULL); + assert(result != NULL); + assert(test_output != NULL); + + status = tftf_nvm_read(TEST_NVM_TESTCASE_RESULTS_OFFSET + + (testcase->index * sizeof(TESTCASE_RESULT)), + result, sizeof(TESTCASE_RESULT)); + if (status != STATUS_SUCCESS) { + return status; + } + + output_size = result->output_size; + + if (output_size != 0) { + status = tftf_nvm_read(TEST_NVM_RESULT_BUFFER_OFFSET + + result->output_offset, + test_output, output_size); + if (status != STATUS_SUCCESS) + return status; + } + + test_output[output_size] = 0; + + return STATUS_SUCCESS; +} + +STATUS tftf_get_testcase_index(TESTCASE_FUNC testcase_function, + unsigned *testsuite_index, + unsigned *testcase_index, + unsigned get_next) +{ + unsigned i, j; + + if (!testcase_function || !testsuite_index || !testcase_index) { + return STATUS_INVALID_PARAMETER; + } + + for (i = 0; testsuites[i].name != NULL; i++) { + for (j = 0; testsuites[i].testcases[j].name != NULL; j++) { + if (testcase_function == testsuites[i].testcases[j].test) { + /* Find the next testcase */ + if (get_next) { + if (testsuites[i].testcases[j+1].name != NULL) { + *testsuite_index = i; + *testcase_index = j+1; + } else if (testsuites[i+1].testcases != NULL) { + *testsuite_index = i+1; + *testcase_index = 0; + } else { + return STATUS_NOT_FOUND; + } + } else { + *testsuite_index = i; + *testcase_index = j; + } + return STATUS_SUCCESS; + } + } + } + return STATUS_NOT_FOUND; +} + +STATUS test_set_passed_and_next(TESTCASE_FUNC testcase_function) +{ + STATUS status; + unsigned testsuite_index, testcase_index; + unsigned next_testsuite_index, next_testcase_index; + + status = tftf_get_testcase_index(testcase_function, &testsuite_index, + &testcase_index, 0); + if (status != STATUS_SUCCESS) + return status; + + status = tftf_get_testcase_index(testcase_function, + &next_testsuite_index, + &next_testcase_index, + 1); + if (status != STATUS_SUCCESS) + return status; + + /* Set the NVM to resume the test execution */ + tftf_set_next_testcase(testsuites[next_testsuite_index].testcases[next_testcase_index].test); + tftf_set_current_testcase(NULL); + + /* + * Assume the test has passed + * if it fails then we will overwrite the result + */ + return tftf_testcase_set_result(&testsuites[testsuite_index].testcases[testcase_index], + TEST_RESULT_SUCCESS, NULL, 0); +} + +STATUS tftf_testcase_set_result_as_crashed(TESTCASE_FUNC crashed_testcase_fn) +{ + STATUS status; + unsigned testsuite_index, testcase_index; + + status = tftf_get_testcase_index(crashed_testcase_fn, &testsuite_index, &testcase_index, 0); + if (status != STATUS_SUCCESS) { + return status; + } + + return tftf_testcase_update_result(&testsuites[testsuite_index].testcases[testcase_index], + TEST_RESULT_CRASHED); +} diff --git a/framework/platform.c b/framework/platform.c deleted file mode 100644 index 1fa16b3..0000000 --- a/framework/platform.c +++ /dev/null @@ -1,47 +0,0 @@ -/** @file -* -* Copyright (c) 2013-2014, ARM Limited. All rights reserved. -* -* This program and the accompanying materials -* are licensed and made available under the terms and conditions of the BSD License -* which accompanies this distribution. The full text of the license may be found at -* http://opensource.org/licenses/bsd-license.php -* -* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -* -**/ - -#include <tftf.h> -#include <psci.h> -#include <arch_helpers.h> -#include <platform.h> - -__attribute__((weak)) unsigned long long tftf_platform_get_time(void) { - return 0; -} - -__attribute__((weak)) void tftf_platform_end(void) { - -} - -__attribute__((weak)) void tftf_platform_reset(void) { - -} - -__attribute__((weak)) void tftf_platform_watchdog_set(void) { - -} - -__attribute__((weak)) void tftf_platform_watchdog_reset(void) { - -} - -__attribute__((weak)) unsigned tftf_platform_core_whoami(void) { - unsigned mpidr = read_mpidr(); - return platform_get_core_pos(mpidr); -} - -__attribute__((weak)) unsigned tftf_platform_core_pos_to_mpid(unsigned core_pos) { - return 0; -} diff --git a/framework/psci.c b/framework/psci.c deleted file mode 100644 index 6334e06..0000000 --- a/framework/psci.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <psci.h> -#include <tftf.h> - -uint32_t tftf_psci_cpu_on(uint64_t target_cpu, - uint64_t entry_point_address, - uint64_t context_id) -{ - smc64_args args = { - PSCI_CPU_ON_AARCH64, - target_cpu, - entry_point_address, - context_id - }; - smc64_ret_values ret_vals; - - ret_vals = tftf_smc64(&args); - - return ret_vals.ret0; -} - -uint32_t tftf_psci_cpu_off(void) -{ - smc64_args args = { PSCI_CPU_OFF }; - smc64_ret_values ret_vals; - - ret_vals = tftf_smc64(&args); - - return ret_vals.ret0; -} diff --git a/framework/smc.c b/framework/smc.c deleted file mode 100644 index 6cba7c3..0000000 --- a/framework/smc.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <tftf.h> -#include <stdint.h> - -/* - * Defined in tftf_asm_helpers.S - * Note: This function must not be inlined, otherwise we can't rely on the - * AAPCS64. - */ -__noinline smc64_ret_values asm_tftf_smc64(uint64_t arg0, - uint64_t arg1, - uint64_t arg2, - uint64_t arg3, - uint64_t arg4, - uint64_t arg5, - uint64_t arg6); - -smc64_ret_values tftf_smc64(const smc64_args *args) -{ - return asm_tftf_smc64(args->arg0, - args->arg1, - args->arg2, - args->arg3, - args->arg4, - args->arg5, - args->arg6); -} diff --git a/framework/systimer.c b/framework/systimer.c deleted file mode 100644 index 76f9cd2..0000000 --- a/framework/systimer.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <assert.h> - -#include <tftf.h> -#include <arch_helpers.h> -#include <platform.h> -#include <mmio.h> -#include <irq.h> -#include <spinlock.h> -#include <stdio.h> - -static unsigned int systimer_init = 0; - -/* Lock to avoid concurrent accesses to the send_sgis_cpu */ -static spinlock_t sgi_dest_lock; - -/* Each bit corresponds to the CPU to which SGI needs to be sent */ -static unsigned int send_sgis_cpu; - -int tftf_systimer_handler(void *data) -{ - uint32_t val; - unsigned int i; - -#ifndef NDEBUG - /* Ensure this is the irq we expect */ - unsigned int irq_id = *(unsigned int *) data; - assert(irq_id == IRQ_CNTPSIRQ1); -#endif - - /* Deassert the timer interrupt */ - val = mmio_read_32(SYS_CNT_BASE1 + CNTP_CTL); - set_cntp_ctl_imask(val); - mmio_write_32(SYS_CNT_BASE1 + CNTP_CTL, val); - - /* Disable the timer */ - val = 0; - set_cntp_ctl_imask(val); - mmio_write_32(SYS_CNT_BASE1 + CNTP_CTL, val); - - /* We expect the timer management CPU is always CPU 0 */ - assert((read_mpidr() & 0xffff) == tftf_platform_core_pos_to_mpid(0)); - - /* Send interrupts to all the CPUS which registered */ - if (send_sgis_cpu) { - spin_lock(&sgi_dest_lock); - for (i = 1; i < PLATFORM_CORE_COUNT; i++) - if (send_sgis_cpu & (1 << i)) - tftf_send_sgi(IRQ_WAKE_SGI, i); - - /* clear the request once the interrupts are sent */ - send_sgis_cpu = 0; - spin_unlock(&sgi_dest_lock); - } - - return 0; -} - -void tftf_systimer_fire_in(uint64_t time_ms) -{ - uint32_t freq; - uint32_t cntp_ctl; - uint64_t count_val; - uint64_t delta; - - /* First ensure the timer has been initialised */ - assert(systimer_init == 1); - - /* Program the timer value to fire in 'time_ms' ms from now */ - freq = read_cntfrq_el0(); - delta = (freq * time_ms) / 1000; - count_val = mmio_read_64(SYS_CNT_BASE1 + CNTPCT_LO); - count_val += delta; - mmio_write_64(SYS_CNT_BASE1 + CNTP_CVAL_LO, count_val); - - /* Enable the timer */ - cntp_ctl = mmio_read_32(SYS_CNT_BASE1 + CNTP_CTL); - set_cntp_ctl_enable(cntp_ctl); - clr_cntp_ctl_imask(cntp_ctl); - mmio_write_32(SYS_CNT_BASE1 + CNTP_CTL, cntp_ctl); -} - -int tftf_systimer_setup(void) -{ - uint32_t cntp_ctl; - int rc = 0; - - /* TODO: Ensure only the primary cpu calls this function */ - - /* Disable the timer as the reset value is unknown */ - cntp_ctl = 0; - set_cntp_ctl_imask(cntp_ctl); - mmio_write_32(SYS_CNT_BASE1 + CNTP_CTL, cntp_ctl); - - /* Register the system timer irq */ - rc = tftf_irq_register(IRQ_CNTPSIRQ1, tftf_systimer_handler); - if (rc != 0) - goto exit_setup; - - systimer_init = 1; - -exit_setup: - return rc; -} - -void tftf_register_sgi_wake_interrupt(unsigned int core_pos) -{ - spin_lock(&sgi_dest_lock); - send_sgis_cpu = send_sgis_cpu | (1 << core_pos); - spin_unlock(&sgi_dest_lock); -} - diff --git a/framework/trusted_os.c b/framework/trusted_os.c deleted file mode 100644 index 3c9fcf1..0000000 --- a/framework/trusted_os.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdint.h> -#include <smc.h> -#include <tftf.h> -#include <trusted_os.h> -#include <uuid_utils.h> - -unsigned int is_trusted_os_present(uuid_t *tos_uuid) -{ - smc64_args tos_uid_args = { TOS_UID }; - smc64_ret_values ret; - uint32_t *tos_uuid32; - - ret = tftf_smc64(&tos_uid_args); - - if ((ret.ret0 == SMC_UNKNOWN) || - ((ret.ret0 == 0) && (ret.ret1 == 0) && (ret.ret2 == 0) && - (ret.ret3 == 0))) - return 0; - - tos_uuid32 = (uint32_t *) tos_uuid; - tos_uuid32[0] = ret.ret0; - tos_uuid32[1] = ret.ret1; - tos_uuid32[2] = ret.ret2; - tos_uuid32[3] = ret.ret3; - - return 1; -} |